From 282d63da36049746410cfc0462169900e29fd071 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 10 Jan 2024 10:18:10 +0100 Subject: [PATCH 001/150] [sinttest] Minor fixes in AdHocCommandIntegrationTest --- .../smackx/commands/AdHocCommandIntegrationTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandIntegrationTest.java index b4821f48e..f29f07f91 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandIntegrationTest.java @@ -1,6 +1,6 @@ /** * - * Copyright 2023 Florian Schmaus + * Copyright 2023-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -93,7 +93,7 @@ public class AdHocCommandIntegrationTest extends AbstractSmackIntegrationTest { private static DataForm createDataFormOp() { FormField field = FormField.listSingleBuilder("op") - .setLabel("Arthimetic Operation") + .setLabel("Arithmetic Operation") .setRequired() .addOption("+") .addOption("-") @@ -118,7 +118,6 @@ public class AdHocCommandIntegrationTest extends AbstractSmackIntegrationTest { NextStage.nonFinal).build(); } - // TODO: Add API for every case where we return null or throw below. private static Integer extractIntegerField(SubmitForm form, String fieldName) throws XMPPErrorException { FormField field = form.getField(fieldName); if (field == null) From 643d85c5563e276d617107a7ca8832ea6185f138 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 10 Jan 2024 10:41:22 +0100 Subject: [PATCH 002/150] [xdata] Fix NPE in FillableForm Calling write() in FillableForm's constructor causes a NPE because write() makes use of requiredFields which has not been set at this time. Furthermore, write() makes use of missingRequiredFields, which is also populated in that loop. Therefore, we have to delay the invocation of write() until requiredFields got set. Thanks to Dan Caseley for reporting this. Reported-by: Dan Caseley --- .../org/jivesoftware/smackx/xdata/form/FillableForm.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/form/FillableForm.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/form/FillableForm.java index c14990a9a..332c7fc3f 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/form/FillableForm.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/form/FillableForm.java @@ -1,6 +1,6 @@ /** * - * Copyright 2020 Florian Schmaus + * Copyright 2020-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,6 +54,7 @@ public class FillableForm extends FilledForm { } Set requiredFields = new HashSet<>(); + List requiredFieldsWithDefaultValue = new ArrayList<>(); for (FormField formField : dataForm.getFields()) { if (formField.isRequired()) { String fieldName = formField.getFieldName(); @@ -61,13 +62,17 @@ public class FillableForm extends FilledForm { if (formField.hasValueSet()) { // This is a form field with a default value. - write(formField); + requiredFieldsWithDefaultValue.add(formField); } else { missingRequiredFields.add(fieldName); } } } this.requiredFields = Collections.unmodifiableSet(requiredFields); + + for (FormField field : requiredFieldsWithDefaultValue) { + write(field); + } } protected void writeListMulti(String fieldName, List values) { From 8b9a9e0f3e11d8a251c01fe68678dfea6c96e05d Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 10 Jan 2024 10:41:22 +0100 Subject: [PATCH 003/150] [xdata] Fix NPE in FillableForm Calling write() in FillableForm's constructor causes a NPE because write() makes use of requiredFields which has not been set at this time. Furthermore, write() makes use of missingRequiredFields, which is also populated in that loop. Therefore, we have to delay the invocation of write() until requiredFields got set. Thanks to Dan Caseley for reporting this. Reported-by: Dan Caseley --- .../org/jivesoftware/smackx/xdata/form/FillableForm.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/form/FillableForm.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/form/FillableForm.java index b40cb92a8..d0657ba08 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/form/FillableForm.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/form/FillableForm.java @@ -1,6 +1,6 @@ /** * - * Copyright 2020 Florian Schmaus + * Copyright 2020-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,6 +55,7 @@ public class FillableForm extends FilledForm { } Set requiredFields = new HashSet<>(); + List requiredFieldsWithDefaultValue = new ArrayList<>(); for (FormField formField : dataForm.getFields()) { if (formField.isRequired()) { String fieldName = formField.getFieldName(); @@ -62,13 +63,17 @@ public class FillableForm extends FilledForm { if (formField.hasValueSet()) { // This is a form field with a default value. - write(formField); + requiredFieldsWithDefaultValue.add(formField); } else { missingRequiredFields.add(fieldName); } } } this.requiredFields = Collections.unmodifiableSet(requiredFields); + + for (FormField field : requiredFieldsWithDefaultValue) { + write(field); + } } protected void writeListMulti(String fieldName, List values) { From 8133505050274bcc9e20fcd04c469d392f880885 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 13 Jan 2024 15:48:29 +0100 Subject: [PATCH 004/150] [websocket] Invoke send listeners --- .../smack/websocket/XmppWebSocketTransportModule.java | 1 + 1 file changed, 1 insertion(+) diff --git a/smack-websocket/src/main/java/org/jivesoftware/smack/websocket/XmppWebSocketTransportModule.java b/smack-websocket/src/main/java/org/jivesoftware/smack/websocket/XmppWebSocketTransportModule.java index 9cfa8fe2f..435373203 100644 --- a/smack-websocket/src/main/java/org/jivesoftware/smack/websocket/XmppWebSocketTransportModule.java +++ b/smack-websocket/src/main/java/org/jivesoftware/smack/websocket/XmppWebSocketTransportModule.java @@ -271,6 +271,7 @@ public final class XmppWebSocketTransportModule asyncButOrderedOutgoingElementsQueue.performAsyncButOrdered(outgoingElementsQueue, () -> { for (TopLevelStreamElement topLevelStreamElement; (topLevelStreamElement = outgoingElementsQueue.poll()) != null;) { websocket.send(topLevelStreamElement); + connectionInternal.fireFirstLevelElementSendListeners(topLevelStreamElement); } }); } From e504bc23cfe601e4e414aac1aff54c8f3d69c67f Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 18 Jan 2024 17:30:44 +0100 Subject: [PATCH 005/150] [extensions] Improve IAE message thrown by FormFieldRegistry --- .../jivesoftware/smackx/formtypes/FormFieldRegistry.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/formtypes/FormFieldRegistry.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/formtypes/FormFieldRegistry.java index 5dda27842..9dae0e1d5 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/formtypes/FormFieldRegistry.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/formtypes/FormFieldRegistry.java @@ -94,7 +94,13 @@ public class FormFieldRegistry { } else { previousType = fieldNameToType.get(fieldName); if (previousType != null && previousType != fieldType) { - throw new IllegalArgumentException(); + String message = "The field '" + fieldName + "' from form type '" + formType + + "' was already registered with field type '" + previousType + + "' while it is now seen with type '" + fieldType + + "'. Form field types have to be unambigiously." + + " XMPP uses a registry for form field tpes, scoped by the form type." + + " You may find the correct value at https://xmpp.org/registrar/formtypes.html"; + throw new IllegalArgumentException(message); } } previousType = fieldNameToType.put(fieldName, fieldType); From a39e5baa741d32af41ac559bbcc7b6233938b725 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 9 Feb 2024 13:17:36 +0100 Subject: [PATCH 006/150] [socks5] Ignore zone IDs of internet addresses Fixes SMACK-940. --- .../smackx/bytestreams/socks5/packet/Bytestream.java | 2 +- .../jingle_s5b/elements/JingleS5BTransportCandidate.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/packet/Bytestream.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/packet/Bytestream.java index 64b3ad7d9..a07dd549e 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/packet/Bytestream.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/packet/Bytestream.java @@ -295,7 +295,7 @@ public class Bytestream extends IQ { * @param port port of the stream host. */ public StreamHost(final Jid jid, final String address, int port) { - this(jid, InternetAddress.from(address), port); + this(jid, InternetAddress.fromIgnoringZoneId(address), port); } public StreamHost(Jid jid, InetAddress address, int port) { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/jingle_s5b/elements/JingleS5BTransportCandidate.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/jingle_s5b/elements/JingleS5BTransportCandidate.java index 4ad96fcca..d3be5a4b3 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/jingle_s5b/elements/JingleS5BTransportCandidate.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/jingle_s5b/elements/JingleS5BTransportCandidate.java @@ -51,7 +51,7 @@ public final class JingleS5BTransportCandidate extends JingleContentTransportCan private final Type type; public JingleS5BTransportCandidate(String candidateId, String hostString, Jid jid, int port, int priority, Type type) { - this(candidateId, InternetAddress.from(hostString), jid, port, priority, type); + this(candidateId, InternetAddress.fromIgnoringZoneId(hostString), jid, port, priority, type); } public JingleS5BTransportCandidate(String candidateId, InternetAddress host, Jid jid, int port, int priority, Type type) { @@ -176,7 +176,7 @@ public final class JingleS5BTransportCandidate extends JingleContentTransportCan } public Builder setHost(String host) { - InternetAddress inetAddress = InternetAddress.from(host); + InternetAddress inetAddress = InternetAddress.fromIgnoringZoneId(host); return setHost(inetAddress); } From f4110ec388c2291fa09d4f6a4cb14bc15806d884 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 14 Mar 2024 10:56:29 +0100 Subject: [PATCH 007/150] SINT: fix typo in output for disabled test --- .../smack/inttest/SmackIntegrationTestFramework.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java index 8be908fb0..a97f96d6c 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java @@ -292,7 +292,7 @@ public class SmackIntegrationTestFramework { } if (config.isClassDisabled(testClass)) { - DisabledTestClass disabledTestClass = new DisabledTestClass(testClass, "Skipping test class " + testClassName + " because it is disalbed"); + DisabledTestClass disabledTestClass = new DisabledTestClass(testClass, "Skipping test class " + testClassName + " because it is disabled"); testRunResult.disabledTestClasses.add(disabledTestClass); continue; } From 449ea732396213095a474f9803c99c38cda0fefa Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 14 Mar 2024 13:14:52 +0100 Subject: [PATCH 008/150] SINT: fix typo in output when using deprecated 'debug' option --- .../java/org/igniterealtime/smack/inttest/Configuration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java index 0df16141c..8af128373 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java @@ -517,7 +517,7 @@ public final class Configuration { String debugString = properties.getProperty("debug"); if (debugString != null) { - LOGGER.warning("Usage of depreacted 'debug' option detected, please use 'debugger' instead"); + LOGGER.warning("Usage of deprecated 'debug' option detected, please use 'debugger' instead"); builder.setDebugger(debugString); } builder.setDebugger(properties.getProperty("debugger")); From ec4caf666359adaa776035ebede6633f804ac333 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 14 Mar 2024 13:15:21 +0100 Subject: [PATCH 009/150] SINT: fix typo in validation of accountTwoPassword argument --- .../java/org/igniterealtime/smack/inttest/Configuration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java index 8af128373..73522ee59 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java @@ -315,7 +315,7 @@ public final class Configuration { this.accountOneUsername = StringUtils.requireNotNullNorEmpty(accountOneUsername, "accountOneUsername must not be null nor empty"); this.accountOnePassword = StringUtils.requireNotNullNorEmpty(accountOnePassword, "accountOnePassword must not be null nor empty"); this.accountTwoUsername = StringUtils.requireNotNullNorEmpty(accountTwoUsername, "accountTwoUsername must not be null nor empty"); - this.accountTwoPassword = StringUtils.requireNotNullNorEmpty(accountTwoPassword, "accountTwoPasswordmust not be null nor empty"); + this.accountTwoPassword = StringUtils.requireNotNullNorEmpty(accountTwoPassword, "accountTwoPassword must not be null nor empty"); this.accountThreeUsername = StringUtils.requireNotNullNorEmpty(accountThreeUsername, "accountThreeUsername must not be null nor empty"); this.accountThreePassword = StringUtils.requireNotNullNorEmpty(accountThreePassword, "accountThreePassword must not be null nor empty"); return this; From 806106534d018dc20c324e84f6e94ba18c147e6f Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 14 Mar 2024 13:18:52 +0100 Subject: [PATCH 010/150] SINT: fix various typos in javadoc and comment --- .../inttest/AbstractSmackLowLevelIntegrationTest.java | 2 +- .../smack/inttest/SmackIntegrationTestFramework.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/AbstractSmackLowLevelIntegrationTest.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/AbstractSmackLowLevelIntegrationTest.java index d517494db..480129575 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/AbstractSmackLowLevelIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/AbstractSmackLowLevelIntegrationTest.java @@ -50,7 +50,7 @@ public abstract class AbstractSmackLowLevelIntegrationTest extends AbstractSmack * Get a connected connection. Note that this method will return a connection constructed via the default connection * descriptor. It is primarily meant for integration tests to discover if the XMPP service supports a certain * feature, that the integration test requires to run. This feature discovery is typically done in the constructor of the - * integration tests. And if the discovery fails a {@link TestNotPossibleException} should be thrown by he constructor. + * integration tests. And if the discovery fails a {@link TestNotPossibleException} should be thrown by the constructor. * *

Please ensure that you invoke {@link #recycle(AbstractXMPPConnection connection)} once you are done with this connection. * diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java index a97f96d6c..554a9d849 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java @@ -494,7 +494,7 @@ public class SmackIntegrationTestFramework { return; } Throwable nonFatalFailureReason; - // junit assert's throw an AssertionError if they fail, those should not be + // junit asserts throw an AssertionError if they fail, those should not be // thrown up, as it would be done by throwFatalException() if (cause instanceof AssertionError) { nonFatalFailureReason = cause; @@ -594,8 +594,8 @@ public class SmackIntegrationTestFramework { throw (InterruptedException) e; } - // We handle NullPointerException as a non fatal exception, as they are mostly caused by an invalid reply where - // a extension element is missing. Consider for example + // We handle NullPointerException as a non-fatal exception, as they are mostly caused by an invalid reply where + // an extension element is missing. Consider for example // assertEquals(StanzaError.Condition.foo, response.getError().getCondition()) // Otherwise NPEs could be caused by an internal bug in Smack, e.g. missing null handling. if (e instanceof NullPointerException) { @@ -613,9 +613,9 @@ public class SmackIntegrationTestFramework { public static final class TestRunResult { /** - * A short String of lowercase characters and numbers used to identify a integration test + * A short String of lowercase characters and numbers used to identify an integration test * run. We use lowercase characters because this string will eventually be part of the - * localpart of the used JIDs (and the localpart is case insensitive). + * localpart of the used JIDs (and the localpart is case-insensitive). */ public final String testRunId = StringUtils.insecureRandomString(5).toLowerCase(Locale.US); From 84a55fa57e22a5a68af09520b380baec3685d8e9 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 14 Mar 2024 16:17:24 +0100 Subject: [PATCH 011/150] fix typos in package-info --- .../java/org/igniterealtime/smack/inttest/package-info.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java index 2caf8d792..0db930e4c 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java @@ -249,7 +249,7 @@ * the required XMPP feature. If it does not, simply throw a TestNotPossibleException. *

*

- * Test methods must be public, take zero arguments i.e. declare no parameters and be annoated with + * Test methods must be public, take zero arguments i.e. declare no parameters and be annotated with * @SmackIntegrationTest. If the test method is not able to perform a test then it should throw a * TestNotPossibleException. *

@@ -266,7 +266,7 @@ *

*

Low-Level Integration Tests

*

- * Classes that implement low-level integration tests need to sublcass + * Classes that implement low-level integration tests need to subclass * {@link org.igniterealtime.smack.inttest.AbstractSmackLowLevelIntegrationTest}. The test methods can declare as many * parameters as they need to, but every parameter must be of type XMPPTCPConnection. The framework will * automatically create, register and login the connections. After the test is finished, the connections will be From 92c45e0d29eef8d52897e698a8c00f78c4c68b62 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 21 Mar 2024 16:18:14 +0100 Subject: [PATCH 012/150] sint: Allow use of custom SmackDebugger Refactors the Smack Integration Test configuration to allow for a classname for a SmackDebugger(Factory) to be provided. --- .../smack/inttest/Configuration.java | 38 ++++++++----------- .../SmackIntegrationTestFramework.java | 9 ++--- .../smack/inttest/package-info.java | 16 +++++++- 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java index 0df16141c..3ab8f9e15 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java @@ -36,6 +36,7 @@ import javax.net.ssl.SSLContext; import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode; import org.jivesoftware.smack.debugger.ConsoleDebugger; +import org.jivesoftware.smack.debugger.SmackDebuggerFactory; import org.jivesoftware.smack.util.CollectionUtil; import org.jivesoftware.smack.util.Function; import org.jivesoftware.smack.util.Objects; @@ -61,12 +62,6 @@ public final class Configuration { serviceAdministration, } - public enum Debugger { - none, - console, - enhanced, - } - public enum DnsResolver { minidns, javax, @@ -101,7 +96,7 @@ public final class Configuration { public final String accountThreePassword; - public final Debugger debugger; + public final SmackDebuggerFactory debuggerFactory; public final Set enabledTests; @@ -148,7 +143,7 @@ public final class Configuration { } else { replyTimeout = 47000; } - debugger = builder.debugger; + debuggerFactory = builder.debuggerFactory; if (StringUtils.isNotEmpty(builder.adminAccountUsername, builder.adminAccountPassword)) { accountRegistration = AccountRegistration.serviceAdministration; } @@ -193,16 +188,8 @@ public final class Configuration { b.setSecurityMode(securityMode); b.setXmppDomain(service); - switch (debugger) { - case enhanced: - b.setDebuggerFactory(EnhancedDebugger.Factory.INSTANCE); - break; - case console: - b.setDebuggerFactory(ConsoleDebugger.Factory.INSTANCE); - break; - case none: - // Nothing to do :). - break; + if (debuggerFactory != null) { + b.setDebuggerFactory(debuggerFactory); } }; @@ -246,7 +233,7 @@ public final class Configuration { public String accountThreePassword; - private Debugger debugger = Debugger.none; + private SmackDebuggerFactory debuggerFactory; private Set enabledTests; @@ -352,18 +339,23 @@ public final class Configuration { case "false": // For backwards compatibility settings with previous boolean setting. LOGGER.warning("Debug string \"" + debuggerString + "\" is deprecated, please use \"none\" instead"); case "none": - debugger = Debugger.none; + debuggerFactory = null; break; case "true": // For backwards compatibility settings with previous boolean setting. LOGGER.warning("Debug string \"" + debuggerString + "\" is deprecated, please use \"console\" instead"); case "console": - debugger = Debugger.console; + debuggerFactory = ConsoleDebugger.Factory.INSTANCE; break; case "enhanced": - debugger = Debugger.enhanced; + debuggerFactory = EnhancedDebugger.Factory.INSTANCE; break; default: - throw new IllegalArgumentException("Unrecognized debugger string: " + debuggerString); + try { + final Class aClass = Class.forName(debuggerString).asSubclass(SmackDebuggerFactory.class); + debuggerFactory = aClass.getConstructor().newInstance(); + } catch (Exception e) { + throw new IllegalArgumentException("Unable to construct debugger from value: " + debuggerString, e); + } } return this; } diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java index 8be908fb0..aedd55221 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java @@ -64,6 +64,7 @@ import org.jivesoftware.smack.util.dns.dnsjava.DNSJavaResolver; import org.jivesoftware.smack.util.dns.javax.JavaxResolver; import org.jivesoftware.smack.util.dns.minidns.MiniDnsResolver; +import org.jivesoftware.smackx.debugger.EnhancedDebugger; import org.jivesoftware.smackx.debugger.EnhancedDebuggerWindow; import org.jivesoftware.smackx.iqregister.AccountManager; @@ -138,12 +139,8 @@ public class SmackIntegrationTestFramework { exitStatus = 0; } - switch (config.debugger) { - case enhanced: + if (config.debuggerFactory instanceof EnhancedDebugger) { EnhancedDebuggerWindow.getInstance().waitUntilClosed(); - break; - default: - break; } System.exit(exitStatus); @@ -175,7 +172,7 @@ public class SmackIntegrationTestFramework { this.connectionManager = new XmppConnectionManager(this); LOGGER.info("SmackIntegrationTestFramework [" + testRunResult.testRunId + ']' + ": Starting\nSmack version: " + Smack.getVersion()); - if (config.debugger != Configuration.Debugger.none) { + if (config.debuggerFactory != null) { // JUL Debugger will not print any information until configured to print log messages of // level FINE // TODO configure JUL for log? diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java index 2caf8d792..46bea2cd0 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java @@ -125,7 +125,7 @@ * * * debugger - * ‘console’ for console debugger, ‘enhanced’ for the enhanced debugger + * ‘console’ for console debugger, ‘enhanced’ for the enhanced debugger, or the name of a class that implements SmackDebuggerFactory for a custom debugger * * * enabledTests @@ -284,6 +284,18 @@ * Debug Window launching when your tests launch, and you'll get a stanza-by-stanza account of what happened on each * connection, hopefully enough to diagnose what went wrong. *

+ *

+ * Lastly, you can provide a custom debugger, by providing the fully qualified name of a class that implements + * {@link org.jivesoftware.smack.debugger.SmackDebuggerFactory}. The provided factory must declare a public constructor + * that takes no arguments. + *

+ *

+ * Example: + *

+ * + *
{@code
+ * $ gradle integrationTest -Dsinttest.service=my.xmppservice.org -Dsinttest.debugger="org.example.MyDebugger$Factory"
+ * }
*

Debugging in the IDE

*

* If the output isn't enough, you may need to debug and inspect running code within the IDE. Depending on the IDE, in @@ -302,7 +314,7 @@ *

* *
{@code
- * $ gradle integrationTest -Dsinttest.service=my.xmppserivce.org -Dsinttest.testPackages=org.mypackage,org.otherpackage
+ * $ gradle integrationTest -Dsinttest.service=my.xmppservice.org -Dsinttest.testPackages=org.mypackage,org.otherpackage
  * }
*/ package org.igniterealtime.smack.inttest; From 6918663760f2a12134027a2b5e268fa18115436d Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 9 Feb 2024 14:13:36 +0100 Subject: [PATCH 013/150] [roster] suppress "roster not loaded while processing presence" if self-presence Fixes SMACK-941. --- .../java/org/jivesoftware/smack/roster/Roster.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java index 02ee0d7e1..6c59b1dc7 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java @@ -1534,11 +1534,20 @@ public final class Roster extends Manager { } } + + final Jid from = packet.getFrom(); + if (!isLoaded() && rosterLoadedAtLogin) { - LOGGER.warning("Roster not loaded while processing " + packet); + XMPPConnection connection = connection(); + + // Only log the warning, if this is not the reflected self-presence. Otherwise, + // the reflected self-presence may cause a spurious warning in case the + // connection got quickly shut down. See SMACK-941. + if (connection != null && from != null && !from.equals(connection.getUser())) { + LOGGER.warning("Roster not loaded while processing " + packet); + } } final Presence presence = (Presence) packet; - final Jid from = presence.getFrom(); final BareJid key; if (from != null) { From 0ca22f22a9853701ed973e762ef2debd4abf5fa1 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 2 Apr 2024 18:28:10 +0200 Subject: [PATCH 014/150] Smack 4.4.8 --- CHANGELOG.md | 12 ++++++++++++ version | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d896bc4e4..b413e7f75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Smack Changelog +# 4.4.8 -- 2024-04-02 + +### Improvement + +[SMACK-941](https://igniterealtime.atlassian.net/browse/SMACK-941) Suppress "roster not loaded while processing presence" warning if its caused by the reflected self-presence + +### Bug + +[SMACK-938](https://igniterealtime.atlassian.net/browse/SMACK-938) Busy loop in SmackReactor + +[SMACK-940](https://igniterealtime.atlassian.net/browse/SMACK-940) Ignore IPv6 Zone IDs in incoming streamhost candidates + # 4.4.7 -- 2023-11-25 ### Improvement diff --git a/version b/version index 030279209..f12d1f240 100644 --- a/version +++ b/version @@ -1 +1 @@ -4.4.8-SNAPSHOT +4.4.8 From 951588e4ed3d80222ebb54eec5e4893ea0ec26c7 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 2 Apr 2024 18:48:17 +0200 Subject: [PATCH 015/150] Smack 4.4.9-SNAPSHOT --- version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version b/version index f12d1f240..ebe9667fc 100644 --- a/version +++ b/version @@ -1 +1 @@ -4.4.8 +4.4.9-SNAPSHOT From d92fef432eb85ca1f30f033db5196c1d889f2225 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 21 Mar 2024 14:42:48 +0100 Subject: [PATCH 016/150] SINT: Expose the test that's being executed --- .../SmackIntegrationTestFramework.java | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java index 8be908fb0..60b39db36 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java @@ -87,6 +87,8 @@ public class SmackIntegrationTestFramework { public static boolean SINTTEST_UNIT_TEST = false; + private static ConcreteTest TEST_UNDER_EXECUTION; + protected final Configuration config; protected TestRunResult testRunResult; @@ -244,6 +246,10 @@ public class SmackIntegrationTestFramework { return testRunResult; } + public static ConcreteTest getTestUnderExecution() { + return TEST_UNDER_EXECUTION; + } + @SuppressWarnings({"Finally"}) private void runTests(Set> classes) throws InterruptedException, InstantiationException, IllegalAccessException, @@ -680,7 +686,12 @@ public class SmackIntegrationTestFramework { executeSinttestSpecialMethod(beforeClassMethod); for (ConcreteTest concreteTest : concreteTests) { - runConcreteTest(concreteTest); + TEST_UNDER_EXECUTION = concreteTest; + try { + runConcreteTest(concreteTest); + } finally { + TEST_UNDER_EXECUTION = null; + } } } finally { @@ -729,21 +740,33 @@ public class SmackIntegrationTestFramework { return null; } - static final class ConcreteTest { + public static final class ConcreteTest { private final TestType testType; private final Method method; private final Executor executor; - private final String[] subdescriptons; + private final List subdescriptons; private ConcreteTest(TestType testType, Method method, Executor executor, String... subdescriptions) { this.testType = testType; this.method = method; this.executor = executor; - this.subdescriptons = subdescriptions; + this.subdescriptons = List.of(subdescriptions); } private transient String stringCache; + public TestType getTestType() { + return testType; + } + + public Method getMethod() { + return method; + } + + public List getSubdescriptons() { + return subdescriptons; + } + @Override public String toString() { if (stringCache != null) { @@ -756,9 +779,9 @@ public class SmackIntegrationTestFramework { .append(method.getName()) .append(" (") .append(testType.name()); - if (subdescriptons != null && subdescriptons.length > 0) { + if (!subdescriptons.isEmpty()) { sb.append(", "); - StringUtils.appendTo(Arrays.asList(subdescriptons), sb); + StringUtils.appendTo(subdescriptons, sb); } sb.append(')'); From dc96484d2b46f88352c6a470270337972c6835ae Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 4 Apr 2024 20:29:32 +0200 Subject: [PATCH 017/150] [sinttest] Add AbstractSmackIntTest.assertResult() --- .../smack/inttest/AbstractSmackIntTest.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/AbstractSmackIntTest.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/AbstractSmackIntTest.java index 2b94b2190..c372103dc 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/AbstractSmackIntTest.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/AbstractSmackIntTest.java @@ -1,6 +1,6 @@ /** * - * Copyright 2015-2020 Florian Schmaus + * Copyright 2015-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,10 @@ import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.StanzaFilter; +import org.igniterealtime.smack.inttest.util.ResultSyncPoint; + +import org.opentest4j.AssertionFailedError; + public abstract class AbstractSmackIntTest { protected static final Logger LOGGER = Logger.getLogger(AbstractSmackIntTest.class.getName()); @@ -90,4 +94,18 @@ public abstract class AbstractSmackIntTest { } return urlConnection; } + + public R assertResult(ResultSyncPoint syncPoint, String message) throws InterruptedException, TimeoutException, AssertionFailedError { + return assertResult(syncPoint, timeout, message); + } + + public static R assertResult(ResultSyncPoint syncPoint, long timeout, String message) throws InterruptedException, TimeoutException, AssertionFailedError { + try { + return syncPoint.waitForResult(timeout); + } catch (InterruptedException | TimeoutException e) { + throw e; + } catch (Exception e) { + throw new AssertionFailedError(message, e); + } + } } From f76f0791e60bb4ca01fc426a28fc81a1c55102ce Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 14 Mar 2024 14:01:21 +0100 Subject: [PATCH 018/150] [sinttest] Add tagging of tests with references to (XMPP) specifications A new annotation is introduced (`SpecificationReference`) that can be used to annotate a SINT test class The properties are available in the annotation: - `document`: Identifier for a specification document, such as 'RFC 6120' or 'XEP-0485' The pre-existing `SmackIntegrationTest` annotation has now received two new properties: - `section`: Identifier for a section (or paragraph), such as '6.2.1' - `quote`: A quotation of relevant text from the section These are expected to be used in context of the `SpecificationReference` annotation. The SINT execution framework is modified so that two new configuration options are available: - `enabledSpecifications` - `disabledSpecifications` These operate on the value of the `document` property of the annotation. Their usage is comparable to that of the pre-existing `enabledTests` and `disabledTest` configuration options. Execution output now includes the document, section and quote that's on the annotated test, when the test fails. This allows an end-user to easily correspond a test failure with a particular specification. --- .../smack/inttest/Configuration.java | 56 +++++++++++++++++++ .../SmackIntegrationTestFramework.java | 52 +++++++++++++++++ .../annotations/SmackIntegrationTest.java | 14 +++++ .../annotations/SpecificationReference.java | 41 ++++++++++++++ .../smack/inttest/package-info.java | 22 ++++++++ 5 files changed, 185 insertions(+) create mode 100644 smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/annotations/SpecificationReference.java diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java index 0df16141c..eaf54e3ba 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java @@ -111,6 +111,10 @@ public final class Configuration { private final Map> disabledTestsMap; + public final Set enabledSpecifications; + + public final Set disabledSpecifications; + public final String defaultConnectionNickname; public final Set enabledConnections; @@ -181,6 +185,8 @@ public final class Configuration { this.enabledTestsMap = convertTestsToMap(enabledTests); this.disabledTests = CollectionUtil.nullSafeUnmodifiableSet(builder.disabledTests); this.disabledTestsMap = convertTestsToMap(disabledTests); + this.enabledSpecifications = CollectionUtil.nullSafeUnmodifiableSet(builder.enabledSpecifications); + this.disabledSpecifications = CollectionUtil.nullSafeUnmodifiableSet(builder.disabledSpecifications); this.defaultConnectionNickname = builder.defaultConnectionNickname; this.enabledConnections = builder.enabledConnections; this.disabledConnections = builder.disabledConnections; @@ -252,6 +258,10 @@ public final class Configuration { private Set disabledTests; + private Set enabledSpecifications; + + private Set disabledSpecifications; + private String defaultConnectionNickname; private Set enabledConnections; @@ -378,6 +388,16 @@ public final class Configuration { return this; } + public Builder setEnabledSpecifications(String enabledSpecificationsString) { + enabledSpecifications = getSpecificationSetFrom(enabledSpecificationsString); + return this; + } + + public Builder setDisabledSpecifications(String disabledSpecificationsString) { + disabledSpecifications = getSpecificationSetFrom(disabledSpecificationsString); + return this; + } + public Builder setDefaultConnection(String defaultConnectionNickname) { this.defaultConnectionNickname = defaultConnectionNickname; return this; @@ -523,6 +543,8 @@ public final class Configuration { builder.setDebugger(properties.getProperty("debugger")); builder.setEnabledTests(properties.getProperty("enabledTests")); builder.setDisabledTests(properties.getProperty("disabledTests")); + builder.setEnabledSpecifications(properties.getProperty("enabledSpecifications")); + builder.setDisabledSpecifications(properties.getProperty("disabledSpecifications")); builder.setDefaultConnection(properties.getProperty("defaultConnection")); builder.setEnabledConnections(properties.getProperty("enabledConnections")); builder.setDisabledConnections(properties.getProperty("disabledConnections")); @@ -587,6 +609,10 @@ public final class Configuration { }); } + private static Set getSpecificationSetFrom(String input) { + return split(input, Configuration::normalizeSpecification); + } + private static Map> convertTestsToMap(Set tests) { Map> res = new HashMap<>(); for (String test : tests) { @@ -695,4 +721,34 @@ public final class Configuration { return contains(method, disabledTestsMap); } + public boolean isSpecificationEnabled(String specification) { + if (enabledSpecifications.isEmpty()) { + return true; + } + + if (specification == null) { + return false; + } + + return enabledSpecifications.contains(normalizeSpecification(specification)); + } + + public boolean isSpecificationDisabled(String specification) { + if (disabledSpecifications.isEmpty()) { + return false; + } + + if (specification == null) { + return false; + } + + return disabledSpecifications.contains(normalizeSpecification(specification)); + } + + static String normalizeSpecification(String specification) { + if (specification == null || specification.isBlank()) { + return null; + } + return specification.replaceAll("\\s", "").toUpperCase(); + } } diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java index 8be908fb0..63e47bf0b 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java @@ -44,6 +44,8 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; @@ -71,6 +73,7 @@ import org.igniterealtime.smack.inttest.Configuration.AccountRegistration; import org.igniterealtime.smack.inttest.annotations.AfterClass; import org.igniterealtime.smack.inttest.annotations.BeforeClass; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.reflections.Reflections; import org.reflections.scanners.MethodAnnotationsScanner; import org.reflections.scanners.MethodParameterScanner; @@ -128,10 +131,21 @@ public class SmackIntegrationTestFramework { final int exitStatus; if (failedTests > 0) { LOGGER.warning("💀 The following " + failedTests + " tests failed! 💀"); + final SortedSet bySpecification = new TreeSet<>(); for (FailedTest failedTest : testRunResult.failedIntegrationTests) { final Throwable cause = failedTest.failureReason; LOGGER.log(Level.SEVERE, failedTest.concreteTest + " failed: " + cause, cause); + if (failedTest.concreteTest.method.isAnnotationPresent(SpecificationReference.class)) { + final String specificationReference = getSpecificationReference(failedTest.concreteTest.method); + if (specificationReference != null) { + bySpecification.add("- " + specificationReference + " (as tested by '" + failedTest.concreteTest + "')"); + } + } } + if (!bySpecification.isEmpty()) { + LOGGER.log(Level.SEVERE, "The failed tests correspond to the following specifications:" + System.lineSeparator() + String.join(System.lineSeparator(), bySpecification)); + } + exitStatus = 2; } else { LOGGER.info("All possible Smack Integration Tests completed successfully. \\o/"); @@ -149,6 +163,24 @@ public class SmackIntegrationTestFramework { System.exit(exitStatus); } + private static String getSpecificationReference(Method method) { + final SpecificationReference spec = method.getDeclaringClass().getAnnotation(SpecificationReference.class); + if (spec == null || spec.document().isBlank()) { + return null; + } + String line = spec.document().trim(); + + final SmackIntegrationTest test = method.getAnnotation(SmackIntegrationTest.class); + if (!test.section().isBlank()) { + line += " section " + test.section().trim(); + } + if (!test.quote().isBlank()) { + line += ":\t\"" + test.quote().trim() + "\""; + } + assert !line.isBlank(); + return line; + } + public SmackIntegrationTestFramework(Configuration configuration) { this.config = configuration; } @@ -297,6 +329,26 @@ public class SmackIntegrationTestFramework { continue; } + final String specification; + if (testClass.isAnnotationPresent(SpecificationReference.class)) { + final SpecificationReference specificationReferenceAnnotation = testClass.getAnnotation(SpecificationReference.class); + specification = Configuration.normalizeSpecification(specificationReferenceAnnotation.document()); + } else { + specification = null; + } + + if (!config.isSpecificationEnabled(specification)) { + DisabledTestClass disabledTestClass = new DisabledTestClass(testClass, "Skipping test method " + testClass + " because it tests a specification ('" + specification + "') that is not enabled"); + testRunResult.disabledTestClasses.add(disabledTestClass); + continue; + } + + if (config.isSpecificationDisabled(specification)) { + DisabledTestClass disabledTestClass = new DisabledTestClass(testClass, "Skipping test method " + testClass + " because it tests a specification ('" + specification + "') that is disabled"); + testRunResult.disabledTestClasses.add(disabledTestClass); + continue; + } + final Constructor cons; try { cons = testClass.getConstructor(SmackIntegrationTestEnvironment.class); diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/annotations/SmackIntegrationTest.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/annotations/SmackIntegrationTest.java index 173b4d2e9..55b1ef684 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/annotations/SmackIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/annotations/SmackIntegrationTest.java @@ -31,4 +31,18 @@ public @interface SmackIntegrationTest { int connectionCount() default -1; + /** + * Unique identifier for a section (or paragraph) of the document referenced by {@link SpecificationReference}, + * such as '6.2.1'. + * + * @return a document section identifier + */ + String section() default ""; + + /** + * A quotation of relevant text from the section referenced by {@link #section()}. + * + * @return human-readable text from the references document and section. + */ + String quote() default ""; } diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/annotations/SpecificationReference.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/annotations/SpecificationReference.java new file mode 100644 index 000000000..947dc3b90 --- /dev/null +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/annotations/SpecificationReference.java @@ -0,0 +1,41 @@ +/** + * + * Copyright 2024 Guus der Kinderen + * + * 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.igniterealtime.smack.inttest.annotations; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Reference to a specific part of a specification. + * + * @author Guus der Kinderen, guus@goodbytes.nl + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface SpecificationReference { + + /** + * Unique identifier for a specification document, such as 'RFC 6120' or 'XEP-0485'. + * + * @return a document identifier + */ + String document(); +} diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java index 2caf8d792..a6692a5c0 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java @@ -136,6 +136,14 @@ * List of disabled tests * * + * enabledSpecifications + * List of specifications for which to enable tests + * + * + * disabledSpecifications + * List of specificatinos for which to disable tests + * + * * defaultConnection * Nickname of the default connection * @@ -187,6 +195,20 @@ *

* would run all tests defined in the SoftwareInfoIntegrationTest class. *

+ *

+ * Use enabledSpecifications to run all tests that assert implementation of functionality that is described + * in standards identified by the provided specification-reference. + *

+ *

+ * For example: + *

+ * + *
+ * $ gradle integrationTest -Dsinttest.enabledSpecifications=XEP-0045
+ * 
+ *

+ * would run all tests that are annotated to verify functionality specified in XEP-0045: "Multi-User Chat". + *

*

Overview of the components

*

* Package org.igniterealtime.smack.inttest From 8839808746107b52348be1d827e27fa149ceace1 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 14 Mar 2024 14:11:40 +0100 Subject: [PATCH 019/150] [sinttest] Retrofit most pre-existing tests to use new tagging This applies the new features from the previous commit, and applies them to pre-existing tests. --- .../smackx/caps/EntityCapsTest.java | 2 + .../chatstate/ChatStateIntegrationTest.java | 2 + .../commands/AdHocCommandIntegrationTest.java | 2 + .../FileTransferIntegrationTest.java | 2 + .../GeolocationIntegrationTest.java | 2 + .../HttpFileUploadIntegrationTest.java | 2 + .../smackx/iot/IoTControlIntegrationTest.java | 2 + .../smackx/iot/IoTDataIntegrationTest.java | 2 + .../iot/IoTDiscoveryIntegrationTest.java | 2 + .../iqversion/VersionIntegrationTest.java | 2 + .../smackx/mam/MamIntegrationTest.java | 2 + .../smackx/mood/MoodIntegrationTest.java | 2 + .../MultiUserChatEntityIntegrationTest.java | 62 ++-- .../muc/MultiUserChatIntegrationTest.java | 40 +-- .../MultiUserChatLowLevelIntegrationTest.java | 2 + ...AffiliationsPrivilegesIntegrationTest.java | 291 ++++++------------ .../MessageEncryptionIntegrationTest.java | 2 + .../smackx/omemo/OmemoMamDecryptionTest.java | 2 + .../omemo/ReadOnlyDeviceIntegrationTest.java | 2 + .../SessionRenegotiationIntegrationTest.java | 2 + .../ox/OXSecretKeyBackupIntegrationTest.java | 4 +- .../OXInstantMessagingIntegrationTest.java | 2 + .../smackx/ping/PingIntegrationTest.java | 2 + .../smackx/pubsub/PubSubIntegrationTest.java | 17 +- .../SoftwareInfoIntegrationTest.java | 2 + .../usertune/UserTuneIntegrationTest.java | 2 + 26 files changed, 176 insertions(+), 280 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/caps/EntityCapsTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/caps/EntityCapsTest.java index 4c373a9ce..bcf23f627 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/caps/EntityCapsTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/caps/EntityCapsTest.java @@ -51,7 +51,9 @@ import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.annotations.AfterClass; import org.igniterealtime.smack.inttest.annotations.BeforeClass; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; +@SpecificationReference(document = "XEP-0115") public class EntityCapsTest extends AbstractSmackIntegrationTest { private final EntityCapsManager ecmTwo; diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/chatstate/ChatStateIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/chatstate/ChatStateIntegrationTest.java index 11e1340f4..fad509c4c 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/chatstate/ChatStateIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/chatstate/ChatStateIntegrationTest.java @@ -27,8 +27,10 @@ import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.annotations.AfterClass; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; +@SpecificationReference(document = "XEP-0085") public class ChatStateIntegrationTest extends AbstractSmackIntegrationTest { // Listener for composing chat state diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandIntegrationTest.java index f29f07f91..6d37399d8 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandIntegrationTest.java @@ -36,7 +36,9 @@ import org.jivesoftware.smackx.xdata.packet.DataForm; import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; +@SpecificationReference(document = "XEP-0050") public class AdHocCommandIntegrationTest extends AbstractSmackIntegrationTest { public AdHocCommandIntegrationTest(SmackIntegrationTestEnvironment environment) { diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferIntegrationTest.java index ac79e46ec..023959539 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferIntegrationTest.java @@ -31,8 +31,10 @@ import org.jivesoftware.smackx.filetransfer.FileTransfer.Status; import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.ResultSyncPoint; +@SpecificationReference(document = "XEP-0096") public class FileTransferIntegrationTest extends AbstractSmackIntegrationTest { private static final int MAX_FT_DURATION = 360; diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/geolocation/GeolocationIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/geolocation/GeolocationIntegrationTest.java index 7e149ff3b..a67a3ee03 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/geolocation/GeolocationIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/geolocation/GeolocationIntegrationTest.java @@ -34,11 +34,13 @@ import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.annotations.AfterClass; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.IntegrationTestRosterUtil; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; import org.junit.jupiter.api.Assertions; import org.jxmpp.util.XmppDateTime; +@SpecificationReference(document = "XEP-0080") public class GeolocationIntegrationTest extends AbstractSmackIntegrationTest { private final GeoLocationManager glm1; diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/httpfileupload/HttpFileUploadIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/httpfileupload/HttpFileUploadIntegrationTest.java index 243bfec36..a823e03ad 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/httpfileupload/HttpFileUploadIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/httpfileupload/HttpFileUploadIntegrationTest.java @@ -36,7 +36,9 @@ import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; +@SpecificationReference(document = "XEP-0363") public class HttpFileUploadIntegrationTest extends AbstractSmackIntegrationTest { private static final int FILE_SIZE = 1024 * 128; diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTControlIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTControlIntegrationTest.java index 498493b5b..1cbf4f2a9 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTControlIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTControlIntegrationTest.java @@ -33,10 +33,12 @@ import org.jivesoftware.smackx.iot.control.element.SetData; import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.IntegrationTestRosterUtil; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; import org.jxmpp.jid.Jid; +@SpecificationReference(document = "XEP-0347") public class IoTControlIntegrationTest extends AbstractSmackIntegrationTest { private final IoTControlManager IoTControlManagerOne; diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDataIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDataIntegrationTest.java index 858eae9a7..c95209cdb 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDataIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDataIntegrationTest.java @@ -37,8 +37,10 @@ import org.jivesoftware.smackx.iot.data.element.TimestampElement; import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.IntegrationTestRosterUtil; +@SpecificationReference(document = "XEP-0347") public class IoTDataIntegrationTest extends AbstractSmackIntegrationTest { private final IoTDataManager iotDataManagerOne; diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDiscoveryIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDiscoveryIntegrationTest.java index df6bf345e..3ef48c837 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDiscoveryIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDiscoveryIntegrationTest.java @@ -34,8 +34,10 @@ import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.jxmpp.jid.Jid; +@SpecificationReference(document = "XEP-0347") public class IoTDiscoveryIntegrationTest extends AbstractSmackIntegrationTest { private final IoTDiscoveryManager discoveryManagerOne; diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iqversion/VersionIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iqversion/VersionIntegrationTest.java index 9e903bbb8..c12ea5370 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iqversion/VersionIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iqversion/VersionIntegrationTest.java @@ -28,7 +28,9 @@ import org.jivesoftware.smackx.iqversion.packet.Version; import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; +@SpecificationReference(document = "XEP-0092") public class VersionIntegrationTest extends AbstractSmackIntegrationTest { public VersionIntegrationTest(SmackIntegrationTestEnvironment environment) { 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 046a33ac6..b9fcbea7e 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 @@ -42,9 +42,11 @@ import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; import org.jxmpp.jid.EntityBareJid; +@SpecificationReference(document = "XEP-0313") public class MamIntegrationTest extends AbstractSmackIntegrationTest { private final MamManager mamManagerConTwo; diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/mood/MoodIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/mood/MoodIntegrationTest.java index 1a83085dc..bdfaa520e 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/mood/MoodIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/mood/MoodIntegrationTest.java @@ -30,10 +30,12 @@ import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.annotations.AfterClass; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.IntegrationTestRosterUtil; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; import org.junit.jupiter.api.Assertions; +@SpecificationReference(document = "XEP-0107") public class MoodIntegrationTest extends AbstractSmackIntegrationTest { private final MoodManager mm1; diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java index 279160c0f..edf71b0a2 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java @@ -34,10 +34,12 @@ import org.jivesoftware.smackx.disco.packet.DiscoverItems; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityFullJid; import org.jxmpp.jid.parts.Resourcepart; +@SpecificationReference(document = "XEP-0045") public class MultiUserChatEntityIntegrationTest extends AbstractMultiUserChatIntegrationTest { public MultiUserChatEntityIntegrationTest(SmackIntegrationTestEnvironment environment) @@ -47,18 +49,14 @@ public class MultiUserChatEntityIntegrationTest extends AbstractMultiUserChatInt } /** - * Asserts that a MUC service can have its features discovered - * - *

From XEP-0045 § 6.2:

- *
- * An entity may wish to discover if a service implements the Multi-User Chat protocol; in order to do so, it - * sends a service discovery information ("disco#info") query to the MUC service's JID. The service MUST return - * its identity and the features it supports. - *
+ * Asserts that a MUC service can have its features discovered. * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "6.2", quote = + "An entity may wish to discover if a service implements the Multi-User Chat protocol; in order to do so, it " + + "sends a service discovery information (\"disco#info\") query to the MUC service's JID. The service MUST " + + "return its identity and the features it supports.") public void mucTestForDiscoveringFeatures() throws Exception { DiscoverInfo info = mucManagerOne.getMucServiceDiscoInfo(mucManagerOne.getMucServiceDomains().get(0)); assertTrue(info.getIdentities().size() > 0); @@ -68,17 +66,13 @@ public class MultiUserChatEntityIntegrationTest extends AbstractMultiUserChatInt /** * Asserts that a MUC Service lists its public rooms. * - *

From XEP-0045 § 6.3:

- *
- * The service discovery items ("disco#items") protocol enables an entity to query a service for a list of - * associated items, which in the case of a chat service would consist of the specific chat rooms hosted by the - * service. The service SHOULD return a full list of the public rooms it hosts (i.e., not return any rooms that - * are hidden). - *
- * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "6.3", quote = + "The service discovery items (\"disco#items\") protocol enables an entity to query a service for a list of " + + "associated items, which in the case of a chat service would consist of the specific chat rooms hosted by the" + + "service. The service SHOULD return a full list of the public rooms it hosts (i.e., not return any rooms that" + + "are hidden).") public void mucTestForDiscoveringRooms() throws Exception { EntityBareJid mucAddressPublic = getRandomRoom("smack-inttest-publicroom"); MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddressPublic); @@ -104,15 +98,11 @@ public class MultiUserChatEntityIntegrationTest extends AbstractMultiUserChatInt /** * Asserts that a MUC Service returns disco info for a room. * - *

From XEP-0045 § 6.4:

- *
- * Using the disco#info protocol, an entity may also query a specific chat room for more detailed information - * about the room....The room MUST return its identity and SHOULD return the features it supports - *
- * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "6.4", quote = + "Using the disco#info protocol, an entity may also query a specific chat room for more detailed information " + + "about the room....The room MUST return its identity and SHOULD return the features it supports") public void mucTestForDiscoveringRoomInfo() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest-discoinfo"); MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); @@ -133,16 +123,12 @@ public class MultiUserChatEntityIntegrationTest extends AbstractMultiUserChatInt /** * Asserts that a MUC Service returns disco info for a room's items. * - *

From XEP-0045 § 6.5:

- *
- * An entity MAY also query a specific chat room for its associated items. An implementation MAY return a list - * of existing occupants if that information is publicly available, or return no list at all if this information is - * kept private. - *
- * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "6.5", quote = + "An entity MAY also query a specific chat room for its associated items. An implementation MAY return a list " + + "of existing occupants if that information is publicly available, or return no list at all if this " + + "information is kept private.") public void mucTestForDiscoveringRoomItems() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest-discoitems"); MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); @@ -162,15 +148,11 @@ public class MultiUserChatEntityIntegrationTest extends AbstractMultiUserChatInt * Asserts that a non-occupant receives a Bad Request error when attempting to query an occupant by their * occupant JID. * - *

From XEP-0045 § 6.6:

- *
- * If a non-occupant attempts to send a disco request to an address of the form <room@service/nick>, a MUC service - * MUST return a <bad-request/> error - *
- * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "6.6", quote = + "If a non-occupant attempts to send a disco request to an address of the form , a MUC " + + "service MUST return a error") public void mucTestForRejectingDiscoOnRoomOccupantByNonOccupant() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest-discoitems"); MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java index 36fa47815..c6e4e9209 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java @@ -34,11 +34,13 @@ import org.jivesoftware.smackx.muc.packet.MUCUser; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.ResultSyncPoint; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.parts.Resourcepart; +@SpecificationReference(document = "XEP-0045") public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrationTest { public MultiUserChatIntegrationTest(SmackIntegrationTestEnvironment environment) @@ -50,15 +52,11 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati /** * Asserts that when a user joins a room, they are themselves included on the list of users notified (self-presence). * - *

From XEP-0045 § 7.2.2:

- *
- * ...the service MUST also send presence from the new participant's occupant JID to the full JIDs of all the - * occupants (including the new occupant) - *
- * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "7.2.2", quote = + "... the service MUST also send presence from the new participant's occupant JID to the full JIDs of all the " + + "occupants (including the new occupant)") public void mucJoinTest() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest-join"); @@ -80,16 +78,12 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati /** * Asserts that when a user leaves a room, they are themselves included on the list of users notified (self-presence). * - *

From XEP-0045 § 7.14:

- *
- * The service MUST then send a presence stanzas of type "unavailable" from the departing user's occupant JID to - * the departing occupant's full JIDs, including a status code of "110" to indicate that this notification is - * "self-presence" - *
- * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "7.14", quote = + "The service MUST then send a presence stanzas of type \"unavailable\" from the departing user's occupant " + + "JID to the departing occupant's full JIDs, including a status code of \"110\" to indicate that this " + + "notification is \"self-presence\"") public void mucLeaveTest() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest-leave"); @@ -144,18 +138,15 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati } - /** - * Asserts that a user is notified when a room is destroyed - * - *

From XEP-0045 § 10.9:

- *
- * A room owner MUST be able to destroy a room, especially if the room is persistent... The room removes all users from the room... and destroys the room - *
+ /** + * Asserts that a user is notified when a room is destroyed. * * @throws TimeoutException when roomDestroyed event doesn't get fired * @throws Exception when other errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "10.9", quote = + "A room owner MUST be able to destroy a room, especially if the room is persistent... The room removes all " + + "users from the room... and destroys the room") public void mucDestroyTest() throws TimeoutException, Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest-destroy"); @@ -190,7 +181,4 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati assertEquals(0, muc.getOccupantsCount()); assertNull(muc.getNickname()); } - - - } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatLowLevelIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatLowLevelIntegrationTest.java index e0f476306..7cc418b2c 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatLowLevelIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatLowLevelIntegrationTest.java @@ -33,11 +33,13 @@ import org.igniterealtime.smack.inttest.AbstractSmackLowLevelIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.jxmpp.jid.DomainBareJid; import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.parts.Localpart; import org.jxmpp.jid.parts.Resourcepart; +@SpecificationReference(document = "XEP-0048") public class MultiUserChatLowLevelIntegrationTest extends AbstractSmackLowLevelIntegrationTest { public MultiUserChatLowLevelIntegrationTest(SmackIntegrationTestEnvironment environment) throws Exception { diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java index d26e22593..b4259bae1 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java @@ -32,6 +32,7 @@ import org.jivesoftware.smackx.muc.packet.MUCUser; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.ResultSyncPoint; import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityFullJid; @@ -40,6 +41,7 @@ import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.parts.Resourcepart; +@SpecificationReference(document = "XEP-0045") public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends AbstractMultiUserChatIntegrationTest{ public MultiUserChatRolesAffiliationsPrivilegesIntegrationTest(SmackIntegrationTestEnvironment environment) @@ -49,23 +51,14 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs } /** - * Asserts that a user who undergoes a role change receives that change as a presence update - * - *

From XEP-0045 § 5.1.3:

- *
- * ...a MUC service implementation MUST change the occupant's role to reflect the change and communicate the change - * to all occupants... - *
- * - *

From XEP-0045 § 9.6:

- *
- * The service MUST then send updated presence from this individual to all occupants, indicating the addition of - * moderator status... - *
+ * Asserts that a user who undergoes a role change receives that change as a presence update. * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "5.1.3", quote = + "(§ 5.1.3)... a MUC service implementation MUST change the occupant's role to reflect the change and " + + "communicate the change to all occupants [...] (§ 9.6) The service MUST then send updated presence from this " + + "individual to all occupants, indicating the addition of moderator status...") public void mucRoleTestForReceivingModerator() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest"); @@ -97,23 +90,14 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs } /** - * Asserts that a user who is present when another user undergoes a role change receives that change as a presence update - * - *

From XEP-0045 § 5.1.3:

- *
- * ...a MUC service implementation MUST change the occupant's role to reflect the change and communicate the change - * to all occupants... - *
- * - *

From XEP-0045 § 9.6:

- *
- * The service MUST then send updated presence from this individual to all occupants, indicating the addition of - * moderator status... - *
+ * Asserts that a user who is present when another user undergoes a role change receives that change as a presence update. * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "9.6", quote = + "(§ 5.1.3)... a MUC service implementation MUST change the occupant's role to reflect the change and " + + "communicate the change to all occupants [...] (§ 9.6) The service MUST then send updated presence from this " + + "individual to all occupants, indicating the addition of moderator status...") public void mucRoleTestForWitnessingModerator() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest"); @@ -146,23 +130,14 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs } /** - * Asserts that a user who undergoes a role change receives that change as a presence update - * - *

From XEP-0045 § 5.1.3:

- *
- * ...a MUC service implementation MUST change the occupant's role to reflect the change and communicate the change - * to all occupants... - *
- * - *

From XEP-0045 § 9.7:

- *
- * The service MUST then send updated presence from this individual to all occupants, indicating the removal of - * moderator status... - *
+ * Asserts that a user who undergoes a role change receives that change as a presence update. * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "5.1.3", quote = + "(§ 5.1.3)... a MUC service implementation MUST change the occupant's role to reflect the change and " + + "communicate the change to all occupants [...] (§ 9.7) The service MUST then send updated presence from this " + + "individual to all occupants, indicating the removal of moderator status...") public void mucRoleTestForRemovingModerator() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest"); @@ -192,23 +167,14 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs } /** - * Asserts that a user who is present when another user undergoes a role change receives that change as a presence update - * - *

From XEP-0045 § 5.1.3:

- *
- * ...a MUC service implementation MUST change the occupant's role to reflect the change and communicate the change - * to all occupants... - *
- * - *

From XEP-0045 § 9.7:

- *
- * The service MUST then send updated presence from this individual to all occupants, indicating the removal of - * moderator status... - *
+ * Asserts that a user who is present when another user undergoes a role change receives that change as a presence update. * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "9.7", quote = + "(§ 5.1.3)... a MUC service implementation MUST change the occupant's role to reflect the change and " + + "communicate the change to all occupants [...] (§ 9.7) The service MUST then send updated presence from this " + + "individual to all occupants, indicating the removal of moderator status...") public void mucRoleTestForWitnessingModeratorRemoval() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest"); @@ -241,23 +207,14 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs } /** - * Asserts that a user in an unmoderated room who undergoes an afilliation change receives that change as a presence update - * - *

From XEP-0045 § 5.1.3:

- *
- * ...a MUC service implementation MUST change the occupant's role to reflect the change and communicate the change - * to all occupants... - *
- * - *

From XEP-0045 § 8.4:

- *
- * The service MUST then send updated presence from this individual to all occupants, indicating the removal of - * voice privileges... - *
+ * Asserts that a user in an unmoderated room who undergoes an afilliation change receives that change as a presence update. * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "5.1.3", quote = + "(§ 5.1.3)... a MUC service implementation MUST change the occupant's role to reflect the change and " + + "communicate the change to all occupants [...] (§ 8.4) The service MUST then send updated presence from " + + "this individual to all occupants, indicating the removal of voice privileges...") public void mucRoleTestForRevokingVoice() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest"); @@ -285,23 +242,14 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs } /** - * Asserts that a user who is present when another user undergoes a role change receives that change as a presence update - * - *

From XEP-0045 § 5.1.3:

- *
- * ...a MUC service implementation MUST change the occupant's role to reflect the change and communicate the change - * to all occupants... - *
- * - *

From XEP-0045 § 8.4:

- *
- * The service MUST then send updated presence from this individual to all occupants, indicating the removal of - * voice privileges... - *
+ * Asserts that a user who is present when another user undergoes a role change receives that change as a presence update. * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "8.4", quote = + "(§ 5.1.3)... a MUC service implementation MUST change the occupant's role to reflect the change and " + + "communicate the change to all occupants [...] (§ 8.4) The service MUST then send updated presence from " + + "this individual to all occupants, indicating the removal of voice privileges...") public void mucRoleTestForWitnessingRevokingVoice() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest"); @@ -333,23 +281,14 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs } /** - * Asserts that a user who undergoes an affiliation change receives that change as a presence update - * - *

From XEP-0045 § 5.2.2:

- *
- * ...a MUC service implementation MUST change the user's affiliation to reflect the change and communicate that - * to all occupants... - *
- * - *

From XEP-0045 § 10.6:

- *
- * If the user is in the room, the service MUST then send updated presence from this individual to all occupants, - * indicating the granting of admin status... - *
+ * Asserts that a user who undergoes an affiliation change receives that change as a presence update. * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "5.2.2", quote = + "(§ 5.2.2) ... a MUC service implementation MUST change the user's affiliation to reflect the change and " + + "communicate that to all occupants [...] (§ 10.6) If the user is in the room, the service MUST then send " + + "updated presence from this individual to all occupants, indicating the granting of admin status...") public void mucAffiliationTestForReceivingAdmin() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest"); @@ -381,23 +320,14 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs /** * Asserts that a user who is present when another user undergoes an affiliation change receives that change as a - * presence update - * - *

From XEP-0045 § 5.2.2:

- *
- * ...a MUC service implementation MUST change the user's affiliation to reflect the change and communicate that - * to all occupants... - *
- * - *

From XEP-0045 § 10.6:

- *
- * If the user is in the room, the service MUST then send updated presence from this individual to all occupants, - * indicating the granting of admin status... - *
+ * presence update. * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "10.6", quote = + "(§ 5.2.2) ... a MUC service implementation MUST change the user's affiliation to reflect the change and " + + "communicate that to all occupants [...] (§ 10.6) If the user is in the room, the service MUST then send " + + "updated presence from this individual to all occupants, indicating the granting of admin status...") public void mucAffiliationTestForWitnessingAdmin() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest"); @@ -429,23 +359,15 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs } /** - * Asserts that a user who undergoes an affiliation change receives that change as a presence update - * - *

From XEP-0045 § 5.2.2:

- *
- * ...a MUC service implementation MUST change the user's affiliation to reflect the change and communicate that to - * all occupants... - *
- * - *

From XEP-0045 § 10.7:

- *
- * If the user is in the room, the service MUST then send updated presence from this individual to all occupants, - * indicating the loss of admin status by sending a presence element... - *
+ * Asserts that a user who undergoes an affiliation change receives that change as a presence update. * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "10.7", quote = + "(§ 5.2.2) ... a MUC service implementation MUST change the user's affiliation to reflect the change and " + + "communicate that to all occupants [...] (§ 10.6) If the user is in the room, the service MUST then send " + + "updated presence from this individual to all occupants, indicating the loss of admin status by sending a " + + "presence element...") public void mucAffiliationTestForRemovingAdmin() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest"); @@ -491,7 +413,11 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "10.7", quote = + "(§ 5.2.2) ... a MUC service implementation MUST change the user's affiliation to reflect the change and " + + "communicate that to all occupants [...] (§ 10.6) If the user is in the room, the service MUST then send " + + "updated presence from this individual to all occupants, indicating the loss of admin status by sending a " + + "presence element...") public void mucAffiliationTestForWitnessingAdminRemoval() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest"); @@ -524,21 +450,16 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs } /** - * Asserts that a user who gets kicked receives that change as a presence update - * - *

From XEP-0045 § 8.2:

- *
- * The kick is performed based on the occupant's room nickname and is completed by setting the role of a - * participant or visitor to a value of "none". - * - * The service MUST remove the kicked occupant by sending a presence stanza of type "unavailable" to each kicked - * occupant, including status code 307 in the extended presence information, optionally along with the reason (if - * provided) and the roomnick or bare JID of the user who initiated the kick. - *
+ * Asserts that a user who gets kicked receives that change as a presence update. * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "8.2", quote = + "The kick is performed based on the occupant's room nickname and is completed by setting the role of a " + + "participant or visitor to a value of \"none\". The service MUST remove the kicked occupant by sending a " + + "presence stanza of type \"unavailable\" to each kicked occupant, including status code 307 in the extended " + + "presence information, optionally along with the reason (if provided) and the roomnick or bare JID of the " + + "user who initiated the kick.") public void mucPresenceTestForGettingKicked() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest"); @@ -572,19 +493,15 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs } /** - * Asserts that a user who is present when another user gets kicked receives that change as a presence update - * - *

From XEP-0045 § 8.2:

- *
- * ...the service MUST then inform all of the remaining occupants that the kicked occupant is no longer in the room - * by sending presence stanzas of type "unavailable" from the individual's roomnick (<room@service/nick>) to all - * the remaining occupants (just as it does when occupants exit the room of their own volition), including the - * status code and optionally the reason and actor. - *
+ * Asserts that a user who is present when another user gets kicked receives that change as a presence update. * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "8.2", quote = + "...the service MUST then inform all of the remaining occupants that the kicked occupant is no longer in the " + + "room by sending presence stanzas of type \"unavailable\" from the individual's roomnick " + + "() to all the remaining occupants (just as it does when occupants exit the room of their " + + "own volition), including the status code and optionally the reason and actor.") public void mucPresenceTestForWitnessingKick() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest"); @@ -624,16 +541,12 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs /** * Asserts that an affiliation is persistent between visits to the room. * - *

From XEP-0045 § 5.2:

- *
- * These affiliations are long-lived in that they persist across a user's visits to the room and are not affected - * by happenings in the room...Affiliations are granted, revoked, and maintained based on the user's bare JID, not - * the nick as with roles. - *
- * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "5.2", quote = + "These affiliations are long-lived in that they persist across a user's visits to the room and are not " + + "affected by happenings in the room...Affiliations are granted, revoked, and maintained based on the user's " + + "bare JID, not the nick as with roles.") public void mucTestPersistentAffiliation() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest"); @@ -665,24 +578,16 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs } /** - * Asserts that a moderator cannot revoke voice from an owner - * - *

From XEP-0045 § 5.1.1:

- *
- * A moderator MUST NOT be able to revoke voice privileges from an admin or owner - *
- * - *

From XEP-0045 § 8.4:

- *
- * A moderator MUST NOT be able to revoke voice from a user whose affiliation is at or above the moderator's level. - * In addition, a service MUST NOT allow the voice privileges of an admin or owner to be removed by anyone. If a - * moderator attempts to revoke voice privileges from such a user, the service MUST deny the request and return a - * <not-allowed/> error to the sender along with the offending item(s) - *
+ * Asserts that a moderator cannot revoke voice from an owner. * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "5.1.1", quote = + "A moderator MUST NOT be able to revoke voice privileges from an admin or owner [...] (§ 8.4) A moderator " + + "MUST NOT be able to revoke voice from a user whose affiliation is at or above the moderator's level. In " + + "addition, a service MUST NOT allow the voice privileges of an admin or owner to be removed by anyone. If a " + + "moderator attempts to revoke voice privileges from such a user, the service MUST deny the request and return " + + "a error to the sender along with the offending item(s)") public void mucTestModeratorCannotRevokeVoiceFromOwner() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest"); @@ -708,16 +613,12 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs * Asserts that a moderator cannot revoke moderator privileges from a moderator with a higher affiliation * than themselves. * - *

From XEP-0045 § 5.1.3 and §5.2.1:

- *
- * A moderator SHOULD NOT be allowed to revoke moderation privileges from someone with a higher affiliation than - * themselves (i.e., an unaffiliated moderator SHOULD NOT be allowed to revoke moderation privileges from an admin - * or an owner, and an admin SHOULD NOT be allowed to revoke moderation privileges from an owner) - *
- * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "5.1.3", quote = + "A moderator SHOULD NOT be allowed to revoke moderation privileges from someone with a higher affiliation " + + "than themselves (i.e., an unaffiliated moderator SHOULD NOT be allowed to revoke moderation privileges from " + + "an admin or an owner, and an admin SHOULD NOT be allowed to revoke moderation privileges from an owner)") public void mucTestModeratorCannotBeRevokedFromHigherAffiliation() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest"); @@ -755,16 +656,12 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs } /** - * Asserts that an unmoderated room assigns the correct default roles for a given affiliation - * - *

From XEP-0045 § 5.1.2:

- *
- * ...the initial default roles that a service SHOULD set based on the user's affiliation... - *
+ * Asserts that an unmoderated room assigns the correct default roles for a given affiliation. * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "5.1.2", quote = + "...the initial default roles that a service SHOULD set based on the user's affiliation...") public void mucTestDefaultRoleForAffiliationInUnmoderatedRoom() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest-unmoderatedroles"); @@ -804,16 +701,12 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs } /** - * Asserts that a moderated room assigns the correct default roles for a given affiliation - * - *

From XEP-0045 § 5.1.2:

- *
- * ...the initial default roles that a service SHOULD set based on the user's affiliation... - *
+ * Asserts that a moderated room assigns the correct default roles for a given affiliation. * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "5.1.2", quote = + "...the initial default roles that a service SHOULD set based on the user's affiliation...") public void mucTestDefaultRoleForAffiliationInModeratedRoom() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest-moderatedroles"); @@ -864,16 +757,12 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs } /** - * Asserts that a members-only room assigns the correct default roles for a given affiliation - * - *

From XEP-0045 § 5.1.2:

- *
- * ...the initial default roles that a service SHOULD set based on the user's affiliation... - *
+ * Asserts that a members-only room assigns the correct default roles for a given affiliation. * * @throws Exception when errors occur */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "5.1.2", quote = + "...the initial default roles that a service SHOULD set based on the user's affiliation...") public void mucTestDefaultRoleForAffiliationInMembersOnlyRoom() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest-membersonlyroles"); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/MessageEncryptionIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/MessageEncryptionIntegrationTest.java index 2efd1fb1a..a8d5fe441 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/MessageEncryptionIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/MessageEncryptionIntegrationTest.java @@ -29,12 +29,14 @@ import org.jivesoftware.smackx.omemo.element.OmemoBundleElement; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; /** * Simple OMEMO message encryption integration test. * During this test Alice sends an encrypted message to Bob. Bob decrypts it and sends a response to Alice. * It is checked whether the messages can be decrypted, and if used up pre-keys result in renewed bundles. */ +@SpecificationReference(document = "XEP-0384") public class MessageEncryptionIntegrationTest extends AbstractTwoUsersOmemoIntegrationTest { public MessageEncryptionIntegrationTest(SmackIntegrationTestEnvironment environment) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMamDecryptionTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMamDecryptionTest.java index 442643071..489dee26c 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMamDecryptionTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMamDecryptionTest.java @@ -35,11 +35,13 @@ import org.jivesoftware.smackx.omemo.util.MessageOrOmemoMessage; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; /** * This test sends a message from Alice to Bob, while Bob has automatic decryption disabled. * Then Bob fetches his Mam archive and decrypts the result. */ +@SpecificationReference(document = "XEP-0384") public class OmemoMamDecryptionTest extends AbstractTwoUsersOmemoIntegrationTest { public OmemoMamDecryptionTest(SmackIntegrationTestEnvironment environment) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/ReadOnlyDeviceIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/ReadOnlyDeviceIntegrationTest.java index 94c671962..ee593c012 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/ReadOnlyDeviceIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/ReadOnlyDeviceIntegrationTest.java @@ -32,7 +32,9 @@ import org.jivesoftware.smackx.omemo.exceptions.UndecidedOmemoIdentityException; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; +@SpecificationReference(document = "XEP-0384") public class ReadOnlyDeviceIntegrationTest extends AbstractTwoUsersOmemoIntegrationTest { public ReadOnlyDeviceIntegrationTest(SmackIntegrationTestEnvironment environment) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, TestNotPossibleException { diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/SessionRenegotiationIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/SessionRenegotiationIntegrationTest.java index c4a649911..e8a48fd7b 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/SessionRenegotiationIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/SessionRenegotiationIntegrationTest.java @@ -24,7 +24,9 @@ import org.jivesoftware.smack.packet.MessageBuilder; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; +@SpecificationReference(document = "XEP-0384") public class SessionRenegotiationIntegrationTest extends AbstractTwoUsersOmemoIntegrationTest { public SessionRenegotiationIntegrationTest(SmackIntegrationTestEnvironment environment) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/OXSecretKeyBackupIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/OXSecretKeyBackupIntegrationTest.java index 60e3361ad..dc64db3a9 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/OXSecretKeyBackupIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/OXSecretKeyBackupIntegrationTest.java @@ -48,9 +48,11 @@ import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.AfterClass; import org.igniterealtime.smack.inttest.annotations.BeforeClass; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.pgpainless.key.OpenPgpV4Fingerprint; import org.pgpainless.key.protection.UnprotectedKeysProtector; +@SpecificationReference(document = "XEP-0374") public class OXSecretKeyBackupIntegrationTest extends AbstractOpenPgpIntegrationTest { private static final String sessionId = StringUtils.randomString(10); @@ -101,7 +103,7 @@ public class OXSecretKeyBackupIntegrationTest extends AbstractOpenPgpIntegration org.apache.commons.io.FileUtils.deleteDirectory(beforePath); } - @SmackIntegrationTest + @SmackIntegrationTest(section = "5") public void test() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException, IOException, InterruptedException, PubSubException.NotALeafNodeException, SmackException.NoResponseException, SmackException.NotConnectedException, XMPPException.XMPPErrorException, diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingIntegrationTest.java index 683bc199a..cb5e914af 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingIntegrationTest.java @@ -39,11 +39,13 @@ import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.AfterClass; import org.igniterealtime.smack.inttest.annotations.BeforeClass; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; import org.pgpainless.decryption_verification.OpenPgpMetadata; import org.pgpainless.key.OpenPgpV4Fingerprint; import org.pgpainless.key.protection.UnprotectedKeysProtector; +@SpecificationReference(document = "XEP-0374") public class OXInstantMessagingIntegrationTest extends AbstractOpenPgpIntegrationTest { private static final String sessionId = StringUtils.randomString(10); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ping/PingIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ping/PingIntegrationTest.java index 65c683093..035b9ed32 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ping/PingIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ping/PingIntegrationTest.java @@ -35,8 +35,10 @@ import org.jivesoftware.smack.XMPPConnection; import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.jxmpp.jid.Jid; +@SpecificationReference(document = "XEP-0199") public class PingIntegrationTest extends AbstractSmackIntegrationTest { public PingIntegrationTest(SmackIntegrationTestEnvironment environment) { diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/pubsub/PubSubIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/pubsub/PubSubIntegrationTest.java index 1890caf2d..4e2377c26 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/pubsub/PubSubIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/pubsub/PubSubIntegrationTest.java @@ -34,8 +34,10 @@ import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.jxmpp.jid.DomainBareJid; +@SpecificationReference(document = "XEP-0060") public class PubSubIntegrationTest extends AbstractSmackIntegrationTest { private final PubSubManager pubSubManagerOne; @@ -82,21 +84,10 @@ public class PubSubIntegrationTest extends AbstractSmackIntegrationTest { } } - /** - - */ - /** * Asserts that an error is returned when a publish request to a node that is both * 'notification-only' as well as 'transient' contains an item element. * - *

From XEP-0060 § 7.1.3.6:

- *
- * If the event type is notification + transient and the publisher provides an item, - * the service MUST bounce the publication request with a <bad-request/> error - * and a pubsub-specific error condition of <item-forbidden/>. - *
- * * @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. @@ -104,7 +95,9 @@ public class PubSubIntegrationTest extends AbstractSmackIntegrationTest { * @see * 7.1.3.6 Request Does Not Match Configuration */ - @SmackIntegrationTest + @SmackIntegrationTest(section = "7.1.3.6", quote = + "If the event type is notification + transient and the publisher provides an item, the service MUST bounce " + + "the publication request with a error and a pubsub-specific error condition of .") public void transientNotificationOnlyNodeWithItemTest() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { final String nodename = "sinttest-transient-notificationonly-withitem-nodename-" + testRunId; final String itemId = "sinttest-transient-notificationonly-withitem-itemid-" + testRunId; diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/softwareInfo/SoftwareInfoIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/softwareInfo/SoftwareInfoIntegrationTest.java index 3bf111f53..64374e173 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/softwareInfo/SoftwareInfoIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/softwareInfo/SoftwareInfoIntegrationTest.java @@ -33,8 +33,10 @@ import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.annotations.BeforeClass; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.IntegrationTestRosterUtil; +@SpecificationReference(document = "XEP-0232") public class SoftwareInfoIntegrationTest extends AbstractSmackIntegrationTest { public final SoftwareInfoManager sim1; 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 index 653bded72..db3275d00 100644 --- 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 @@ -32,10 +32,12 @@ import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.annotations.AfterClass; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.IntegrationTestRosterUtil; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; import org.junit.jupiter.api.Assertions; +@SpecificationReference(document = "XEP-0118") public class UserTuneIntegrationTest extends AbstractSmackIntegrationTest { private final UserTuneManager utm1; From 2298364384c38b43f1dbc0c6dc8d9f7ffb40c510 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Fri, 5 Apr 2024 16:51:26 +0200 Subject: [PATCH 020/150] [sinttest] Assertions to have human readable messages This adds human-readable text to nearly all assertions in SINT. It is intended that these, together with an XMPP dump of the traffic that was exchanged during the test, allows an observer to have a chance to determine why a particular test failed, without analyzing the test code itself. --- .../smack/LoginIntegrationTest.java | 3 +- .../smack/StreamManagementTest.java | 13 +- .../WaitForClosingStreamElementTest.java | 2 +- .../smack/roster/RosterIntegrationTest.java | 13 +- .../smackx/caps/EntityCapsTest.java | 29 +-- .../chatstate/ChatStateIntegrationTest.java | 2 +- .../commands/AdHocCommandIntegrationTest.java | 18 +- .../FileTransferIntegrationTest.java | 10 +- .../GeolocationIntegrationTest.java | 24 +-- .../HttpFileUploadIntegrationTest.java | 2 +- .../smackx/iot/IoTControlIntegrationTest.java | 2 +- .../smackx/iot/IoTDataIntegrationTest.java | 14 +- .../iot/IoTDiscoveryIntegrationTest.java | 2 +- .../iqversion/VersionIntegrationTest.java | 4 +- .../smackx/mam/MamIntegrationTest.java | 24 +-- .../smackx/mood/MoodIntegrationTest.java | 18 +- .../MultiUserChatEntityIntegrationTest.java | 24 +-- .../muc/MultiUserChatIntegrationTest.java | 39 ++-- .../MultiUserChatLowLevelIntegrationTest.java | 2 +- ...AffiliationsPrivilegesIntegrationTest.java | 166 ++++++++++-------- .../AbstractTwoUsersOmemoIntegrationTest.java | 12 +- .../smackx/omemo/OmemoMamDecryptionTest.java | 7 +- .../smackx/pubsub/PubSubIntegrationTest.java | 6 +- .../SoftwareInfoIntegrationTest.java | 3 +- .../usertune/UserTuneIntegrationTest.java | 10 +- 25 files changed, 230 insertions(+), 219 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/LoginIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/LoginIntegrationTest.java index 2c9dbb9ec..63704c2c2 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/LoginIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/LoginIntegrationTest.java @@ -64,7 +64,8 @@ public class LoginIntegrationTest extends AbstractSmackLowLevelIntegrationTest { () -> connection.login(nonExistentUserString, invalidPassword)); SaslNonza.SASLFailure saslFailure = saslErrorException.getSASLFailure(); - assertEquals(SASLError.not_authorized, saslFailure.getSASLError()); + assertEquals(SASLError.not_authorized, saslFailure.getSASLError(), + "Expected the server to return the appropriate SASL failure condition (but it did not)"); } finally { connection.disconnect(); } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/StreamManagementTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/StreamManagementTest.java index c9ca9095b..78d075af3 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/StreamManagementTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/StreamManagementTest.java @@ -32,6 +32,7 @@ import org.igniterealtime.smack.inttest.AbstractSmackSpecificLowLevelIntegration import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.jxmpp.jid.EntityFullJid; public class StreamManagementTest extends AbstractSmackSpecificLowLevelIntegrationTest { @@ -57,7 +58,7 @@ public class StreamManagementTest extends AbstractSmackSpecificLowLevelIntegrati try { send(body1, conOne, conTwo); - assertMessageWithBodyReceived(body1, collector); + assertMessageWithBodyReceived(body1, collector, conTwo.getUser()); conOne.instantShutdown(); @@ -65,10 +66,10 @@ public class StreamManagementTest extends AbstractSmackSpecificLowLevelIntegrati // Reconnect with xep198 conOne.connect().login(); - assertMessageWithBodyReceived(body2, collector); + assertMessageWithBodyReceived(body2, collector, conTwo.getUser()); send(body3, conOne, conTwo); - assertMessageWithBodyReceived(body3, collector); + assertMessageWithBodyReceived(body3, collector, conTwo.getUser()); } finally { collector.cancel(); @@ -84,9 +85,9 @@ public class StreamManagementTest extends AbstractSmackSpecificLowLevelIntegrati from.sendStanza(message); } - private static void assertMessageWithBodyReceived(String body, StanzaCollector collector) throws InterruptedException { + private static void assertMessageWithBodyReceived(String body, StanzaCollector collector, EntityFullJid recipient) throws InterruptedException { Message message = collector.nextResult(); - assertNotNull(message); - assertEquals(body, message.getBody()); + assertNotNull(message, "Expected '" + recipient + "' to receive a message stanza with body '" + body + "', but it didn't receive the message stanza at all."); + assertEquals(body, message.getBody(), "Expected '" + recipient + "'to receive a message stanza with a specific body, but it received a message stanza with a different body."); } } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/WaitForClosingStreamElementTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/WaitForClosingStreamElementTest.java index 2326866c7..dc9153aab 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/WaitForClosingStreamElementTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/WaitForClosingStreamElementTest.java @@ -39,6 +39,6 @@ public class WaitForClosingStreamElementTest extends AbstractSmackLowLevelIntegr Field closingStreamReceivedField = AbstractXMPPConnection.class.getDeclaredField("closingStreamReceived"); closingStreamReceivedField.setAccessible(true); boolean closingStreamReceived = (boolean) closingStreamReceivedField.get(connection); - assertTrue(closingStreamReceived); + assertTrue(closingStreamReceived, "Expected to, but did not, receive a closing stream element on connection " + connection); } } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java index 55aad5c12..5f951c1d5 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java @@ -16,8 +16,6 @@ */ package org.jivesoftware.smack.roster; -import static org.junit.jupiter.api.Assertions.assertTrue; - import java.util.Collection; import java.util.concurrent.TimeoutException; @@ -78,16 +76,16 @@ public class RosterIntegrationTest extends AbstractSmackIntegrationTest { BareJid bareJid = conTwo.getUser().asBareJid(); RosterEntry rosterEntry = rosterOne.getEntry(bareJid); if (rosterEntry == null) { - addedAndSubscribed.signalFailure("No roster entry for " + bareJid); + addedAndSubscribed.signalFailure("Added/Updated entry was not for " + bareJid); return; } String name = rosterEntry.getName(); if (StringUtils.isNullOrEmpty(name)) { - addedAndSubscribed.signalFailure("Roster entry without name"); + addedAndSubscribed.signalFailure("Added/Updated entry without name"); return; } if (!rosterEntry.getName().equals(conTwosRosterName)) { - addedAndSubscribed.signalFailure("Roster name does not match"); + addedAndSubscribed.signalFailure("Added/Updated entry name does not match. Expected: " + conTwosRosterName + " but was: " + rosterEntry.getName()); return; } if (!rosterEntry.getType().equals(ItemType.to)) { @@ -100,8 +98,9 @@ public class RosterIntegrationTest extends AbstractSmackIntegrationTest { try { rosterOne.createItemAndRequestSubscription(conTwo.getUser().asBareJid(), conTwosRosterName, null); - - assertTrue(addedAndSubscribed.waitForResult(2 * connection.getReplyTimeout())); + assertResult(addedAndSubscribed, 2 * connection.getReplyTimeout(), + "A roster entry for " + conTwo.getUser().asBareJid() + " using the name '" + conTwosRosterName + + "' of type 'to' was expected to be added to the roster of " + conOne.getUser() + " (but it was not)."); } finally { rosterTwo.removeSubscribeListener(subscribeListener); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/caps/EntityCapsTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/caps/EntityCapsTest.java index bcf23f627..c18ea490b 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/caps/EntityCapsTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/caps/EntityCapsTest.java @@ -18,6 +18,7 @@ package org.jivesoftware.smackx.caps; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -96,7 +97,9 @@ public class EntityCapsTest extends AbstractSmackIntegrationTest { public void testLocalEntityCaps() throws InterruptedException, NoResponseException, XMPPErrorException, NotConnectedException { final String dummyFeature = getNewDummyFeature(); DiscoverInfo info = EntityCapsManager.getDiscoveryInfoByNodeVer(ecmTwo.getLocalNodeVer()); - assertFalse(info.containsFeature(dummyFeature)); + assertFalse(info.containsFeature(dummyFeature), + "Expected the service discovery info for node '" + ecmTwo.getLocalNodeVer() + + "' to contain the feature '" + dummyFeature + "' (but it did not)."); // TODO Shouldn't this assertion be in a unit test instead of an integration test? dropWholeEntityCapsCache(); @@ -120,8 +123,12 @@ public class EntityCapsTest extends AbstractSmackIntegrationTest { // The other connection has to receive this stanza and record the // information in order for this test to succeed. info = EntityCapsManager.getDiscoveryInfoByNodeVer(ecmTwo.getLocalNodeVer()); - assertNotNull(info); - assertTrue(info.containsFeature(dummyFeature)); + assertNotNull(info, + "Expected '" + conOne.getUser() + "' to have received an 'available' presence from '" + conTwo.getUser() + + "' with a new CAPS 'ver' attribute (but it did not)."); + assertTrue(info.containsFeature(dummyFeature), + "Expected the service discovery info for node '" + ecmTwo.getLocalNodeVer() + + "' to contain the feature '" + dummyFeature + "' (but it did not)."); // TODO As above: shouldn't this assertion be in a unit test instead of an integration test? } /** @@ -148,7 +155,7 @@ public class EntityCapsTest extends AbstractSmackIntegrationTest { // discover that DiscoverInfo info = sdmOne.discoverInfo(conTwo.getUser()); // that discovery should cause a disco#info - assertTrue(discoInfoSend.get()); + assertTrue(discoInfoSend.get(), "Expected '" + conOne.getUser() + "' to have made a disco/info request to '" + conTwo.getUser() + "', but it did not."); assertTrue(info.containsFeature(dummyFeature), "The info response '" + info + "' does not contain the expected feature '" + dummyFeature + '\''); discoInfoSend.set(false); @@ -156,8 +163,9 @@ public class EntityCapsTest extends AbstractSmackIntegrationTest { // discover that info = sdmOne.discoverInfo(conTwo.getUser()); // that discovery shouldn't cause a disco#info - assertFalse(discoInfoSend.get()); - assertTrue(info.containsFeature(dummyFeature)); + assertFalse(discoInfoSend.get(), "Expected '" + conOne.getUser() + "' to not have made a disco/info request to '" + conTwo.getUser() + "' (as CAPS should have been cached), but it did not."); + assertTrue(info.containsFeature(dummyFeature), + "The info response '" + info + "' does not contain the expected feature '" + dummyFeature + '\''); } @SmackIntegrationTest @@ -167,7 +175,8 @@ public class EntityCapsTest extends AbstractSmackIntegrationTest { addFeatureAndWaitForPresence(conOne, conTwo, dummyFeature); String nodeVerAfter = EntityCapsManager.getNodeVersionByJid(conTwo.getUser()); - assertFalse(nodeVerBefore.equals(nodeVerAfter)); + assertNotEquals(nodeVerBefore, nodeVerAfter, + "Expected the reported node 'ver' value to differ after a feature was added (but it did not)."); } @SmackIntegrationTest @@ -193,12 +202,12 @@ public class EntityCapsTest extends AbstractSmackIntegrationTest { DiscoverInfo info = sdmOne.discoverInfo(conTwo.getUser()); String u1ver = EntityCapsManager.getNodeVersionByJid(conTwo.getUser()); - assertNotNull(u1ver); + assertNotNull(u1ver, "Expected " + conOne.getUser() + " to have received a CAPS 'ver' value for " + conTwo.getUser() + " (but did not)."); DiscoverInfo entityInfo = EntityCapsManager.CAPS_CACHE.lookup(u1ver); - assertNotNull(entityInfo); + assertNotNull(entityInfo, "Expected the local static cache to have a value cached for 'ver' value '" + u1ver + "' (but it did not)."); - assertEquals(info.toXML().toString(), entityInfo.toXML().toString()); + assertEquals(info.toXML().toString(), entityInfo.toXML().toString(), "Expected the cached service/discovery info to be equal to the original (but it was not)."); } private static void dropWholeEntityCapsCache() { diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/chatstate/ChatStateIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/chatstate/ChatStateIntegrationTest.java index fad509c4c..749b39caf 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/chatstate/ChatStateIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/chatstate/ChatStateIntegrationTest.java @@ -75,7 +75,7 @@ public class ChatStateIntegrationTest extends AbstractSmackIntegrationTest { Chat chat = ChatManager.getInstanceFor(conOne) .chatWith(conTwo.getUser().asEntityBareJid()); chat.send("Hi!"); - activeSyncPoint.waitForResult(timeout); + assertResult(activeSyncPoint, "Expected " + conTwo.getUser() + " to receive an 'active' chat state from " + conOne + " (but they did not)."); } @AfterClass diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandIntegrationTest.java index 6d37399d8..521692148 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandIntegrationTest.java @@ -73,7 +73,9 @@ public class AdHocCommandIntegrationTest extends AbstractSmackIntegrationTest { AdHocCommandData response = result.getResponse(); DataForm form = response.getForm(); FormField field = form.getField("my-field"); - assertNotNull(field); + assertNotNull(field, "Expected a field named 'my-field' to exist in the form that " + + conTwo.getUser() + " obtained from " + conOne.getUser() + "'s command node '" + commandNode + + "' (but it did not)."); } finally { manOne.unregisterCommand(commandNode); } @@ -259,7 +261,10 @@ public class AdHocCommandIntegrationTest extends AbstractSmackIntegrationTest { AdHocCommandResult.StatusCompleted completed = command.complete(submitForm).asCompletedOrThrow(); String operationResult = completed.getResponse().getForm().getField("result").getFirstValue(); - assertEquals("65", operationResult); + assertEquals("65", operationResult, + "Unexpected value in the field 'result' from the command result that " + conTwo.getUser() + + " received from " + conOne.getUser() + " after completing a multi-staged ad-hoc command on node '" + + commandNode + "'."); } finally { manTwo.unregisterCommand(commandNode); } @@ -317,7 +322,10 @@ public class AdHocCommandIntegrationTest extends AbstractSmackIntegrationTest { AdHocCommandResult.StatusCompleted completed = command.complete(submitForm).asCompletedOrThrow(); String operationResult = completed.getResponse().getForm().getField("result").getFirstValue(); - assertEquals("100", operationResult); + assertEquals("100", operationResult, + "Unexpected value in the field 'result' from the command result that " + conTwo.getUser() + + " received from " + conOne.getUser() + " after completing a multi-staged ad-hoc command on node '" + + commandNode + "'."); } finally { manTwo.unregisterCommand(commandNode); } @@ -346,7 +354,9 @@ public class AdHocCommandIntegrationTest extends AbstractSmackIntegrationTest { SubmitForm submitForm = form.getSubmitForm(); XMPPErrorException exception = assertThrows(XMPPErrorException.class, () -> command.next(submitForm)); - assertEquals(exception.getStanzaError().getCondition(), StanzaError.Condition.bad_request); + assertEquals(exception.getStanzaError().getCondition(), StanzaError.Condition.bad_request, + "Unexpected error condition received after " + conTwo.getUser() + " supplied an invalid argument " + + "to the command node '" + commandNode + "' of " + conOne.getUser()); } finally { manTwo.unregisterCommand(commandNode); } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferIntegrationTest.java index 023959539..f2addc2ae 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferIntegrationTest.java @@ -32,7 +32,7 @@ import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; import org.igniterealtime.smack.inttest.annotations.SpecificationReference; -import org.igniterealtime.smack.inttest.util.ResultSyncPoint; +import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; @SpecificationReference(document = "XEP-0096") public class FileTransferIntegrationTest extends AbstractSmackIntegrationTest { @@ -67,7 +67,7 @@ public class FileTransferIntegrationTest extends AbstractSmackIntegrationTest { } private void genericfileTransferTest() throws Exception { - final ResultSyncPoint resultSyncPoint = new ResultSyncPoint<>(); + final SimpleResultSyncPoint resultSyncPoint = new SimpleResultSyncPoint(); final FileTransferListener receiveListener = new FileTransferListener() { @Override public void fileTransferRequest(FileTransferRequest request) { @@ -84,7 +84,7 @@ public class FileTransferIntegrationTest extends AbstractSmackIntegrationTest { os.flush(); dataReceived = os.toByteArray(); if (Arrays.equals(dataToSend, dataReceived)) { - resultSyncPoint.signal("Received data matches send data. \\o/"); + resultSyncPoint.signal(); } else { resultSyncPoint.signal(new Exception("Received data does not match")); @@ -117,7 +117,9 @@ public class FileTransferIntegrationTest extends AbstractSmackIntegrationTest { } } - resultSyncPoint.waitForResult(MAX_FT_DURATION * 1000); + assertResult(resultSyncPoint, MAX_FT_DURATION * 1000, + "Expected data to be transferred successfully from " + conOne.getUser() + " to " + conTwo.getUser() + + " (but it did not)."); ftManagerTwo.removeFileTransferListener(receiveListener); } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/geolocation/GeolocationIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/geolocation/GeolocationIntegrationTest.java index a67a3ee03..b58c04b71 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/geolocation/GeolocationIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/geolocation/GeolocationIntegrationTest.java @@ -17,7 +17,6 @@ package org.jivesoftware.smackx.geolocation; import java.net.URI; -import java.util.concurrent.TimeoutException; import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.SmackException.NotConnectedException; @@ -37,7 +36,6 @@ import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.IntegrationTestRosterUtil; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; -import org.junit.jupiter.api.Assertions; import org.jxmpp.util.XmppDateTime; @SpecificationReference(document = "XEP-0080") @@ -108,14 +106,9 @@ public class GeolocationIntegrationTest extends AbstractSmackIntegrationTest { glm1.publishGeoLocation(data); // for the purpose of this test, this needs not be blocking/use publishAndWait(); // Wait for the data to be received. - try { - Object result = geoLocationReceived.waitForResult(timeout); - - // Explicitly assert the success case. - Assertions.assertNotNull(result, "Expected to receive a PEP notification, but did not."); - } catch (TimeoutException e) { - Assertions.fail("Expected to receive a PEP notification, but did not."); - } + assertResult(geoLocationReceived, + "Expected " + conTwo.getUser() + " to receive a PEP notification from " + conOne.getUser() + + " that contained '" + data.toXML() + "', but did not."); } finally { unregisterListener(glm2, geoLocationListener); } @@ -173,14 +166,9 @@ public class GeolocationIntegrationTest extends AbstractSmackIntegrationTest { registerListenerAndWait(glm2, ServiceDiscoveryManager.getInstanceFor(conTwo), geoLocationListener); // Wait for the data to be received. - try { - Object result = geoLocationReceived.waitForResult(timeout); - - // Explicitly assert the success case. - Assertions.assertNotNull(result, "Expected to receive a PEP notification, but did not."); - } catch (TimeoutException e) { - Assertions.fail("Expected to receive a PEP notification, but did not."); - } + assertResult(geoLocationReceived, + "Expected " + conTwo.getUser() + " to receive a PEP notification from " + conOne.getUser() + + " that contained '" + data.toXML() + "', but did not."); } finally { unregisterListener(glm2, geoLocationListener); } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/httpfileupload/HttpFileUploadIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/httpfileupload/HttpFileUploadIntegrationTest.java index a823e03ad..8c92d8f1c 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/httpfileupload/HttpFileUploadIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/httpfileupload/HttpFileUploadIntegrationTest.java @@ -104,6 +104,6 @@ public class HttpFileUploadIntegrationTest extends AbstractSmackIntegrationTest byte[] downBytes = baos.toByteArray(); - assertArrayEquals(upBytes, downBytes); + assertArrayEquals(upBytes, downBytes, "Expected the downloaded bytes to be equal to the uploaded bytes (but they were not)."); } } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTControlIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTControlIntegrationTest.java index 1cbf4f2a9..903e17810 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTControlIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTControlIntegrationTest.java @@ -89,7 +89,7 @@ public class IoTControlIntegrationTest extends AbstractSmackIntegrationTest { SetData data = new SetBoolData(testRunId, true); IoTSetResponse response = IoTControlManagerTwo.setUsingIq(conOne.getUser(), data); - assertNotNull(response); + assertNotNull(response, "Expected " + conOne.getUser() + " to receive an IQ response with an 'setResponse' child element, but no such response was received."); } finally { IoTControlManagerOne.uninstallThing(controlThing); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDataIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDataIntegrationTest.java index c95209cdb..fe4e39124 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDataIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDataIntegrationTest.java @@ -86,23 +86,23 @@ public class IoTDataIntegrationTest extends AbstractSmackIntegrationTest { IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); } - assertEquals(1, values.size()); + assertEquals(1, values.size(), "An unexpected amount of momentary values was received by " + conOne.getUser()); IoTFieldsExtension iotFieldsExtension = values.get(0); List nodes = iotFieldsExtension.getNodes(); - assertEquals(1, nodes.size()); + assertEquals(1, nodes.size(), "The momentary value received by " + conOne.getUser() + " contains an unexpected amount of nodes."); NodeElement node = nodes.get(0); List timestamps = node.getTimestampElements(); - assertEquals(1, timestamps.size()); + assertEquals(1, timestamps.size(), "The node received by " + conOne.getUser() + " contains an unexpected amount of timestamps."); TimestampElement timestamp = timestamps.get(0); List fields = timestamp.getDataFields(); - assertEquals(1, fields.size()); + assertEquals(1, fields.size(), "The timestamp received by " + conOne.getUser() + " contains an unexpected amount of data fields."); IoTDataField dataField = fields.get(0); - assertTrue(dataField instanceof IoTDataField.IntField); + assertTrue(dataField instanceof IoTDataField.IntField, "The data field received by " + conOne.getUser() + " was expected to be an instance of " + IoTDataField.IntField.class.getSimpleName() + ", but instead, it was " + dataField.getClass().getSimpleName()); IoTDataField.IntField intDataField = (IoTDataField.IntField) dataField; - assertEquals(testRunId, intDataField.getName()); - assertEquals(value, intDataField.getValue()); + assertEquals(testRunId, intDataField.getName(), "Unexpected name in the data field received by " + conOne.getUser()); + assertEquals(value, intDataField.getValue(), "Unexpected value in the data field received by " + conOne.getUser()); } } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDiscoveryIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDiscoveryIntegrationTest.java index 3ef48c837..911259040 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDiscoveryIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDiscoveryIntegrationTest.java @@ -62,7 +62,7 @@ public class IoTDiscoveryIntegrationTest extends AbstractSmackIntegrationTest { registerThing(discoveryManagerOne, thing); IoTClaimed iotClaimed = discoveryManagerTwo.claimThing(thing.getMetaTags()); - assertEquals(conOne.getUser().asBareJid(), iotClaimed.getJid()); + assertEquals(conOne.getUser().asBareJid(), iotClaimed.getJid(), "Thing claimed by an unexpected JID"); discoveryManagerTwo.disownThing(iotClaimed.getJid()); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iqversion/VersionIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iqversion/VersionIntegrationTest.java index c12ea5370..dd44d8c03 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iqversion/VersionIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iqversion/VersionIntegrationTest.java @@ -47,8 +47,8 @@ public class VersionIntegrationTest extends AbstractSmackIntegrationTest { final String versionName = "Smack Integration Test " + testRunId; versionManagerTwo.setVersion(versionName, "1.0"); - assertTrue (versionManagerOne.isSupported(conTwo.getUser())); + assertTrue(versionManagerOne.isSupported(conTwo.getUser()), "Expected " + conTwo.getUser() + " to support " + Version.NAMESPACE + " (but it does not)."); Version version = versionManagerOne.getVersion(conTwo.getUser()); - assertEquals(versionName, version.getName()); + assertEquals(versionName, version.getName(), "Unexpected version name reported by " + conTwo.getUser()); } } 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 b9fcbea7e..cb1ebe12b 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 @@ -115,14 +115,14 @@ public class MamIntegrationTest extends AbstractSmackIntegrationTest { .build(); MamQuery mamQuery = mamManagerConTwo.queryArchive(mamQueryArgs); - assertEquals(1, mamQuery.getMessages().size()); + assertEquals(1, mamQuery.getMessages().size(), conTwo.getUser() + " received an unexpected amount of messages in response to a MAM query."); Message mamMessage = mamQuery.getMessages().get(0); - assertEquals(messageId, mamMessage.getStanzaId()); - assertEquals(messageBody, mamMessage.getBody()); - assertEquals(conOne.getUser(), mamMessage.getFrom()); - assertEquals(userTwo, mamMessage.getTo()); + assertEquals(messageId, mamMessage.getStanzaId(), "The message received by " + conTwo.getUser() + " via a MAM query has an unexpected stanza ID."); + assertEquals(messageBody, mamMessage.getBody(), "The message received by " + conTwo.getUser() + " via a MAM query has an unexpected body."); + assertEquals(conOne.getUser(), mamMessage.getFrom(), "The message received by " + conTwo.getUser() + " via a MAM query has an unexpected from-attribute value."); + assertEquals(userTwo, mamMessage.getTo(), "The message received by " + conTwo.getUser() + " via a MAM query has an unexpected to-attribute value."); } @SmackIntegrationTest @@ -176,8 +176,8 @@ public class MamIntegrationTest extends AbstractSmackIntegrationTest { MamQuery mamQuery = mamManagerConTwo.queryArchive(mamQueryArgs); - assertFalse(mamQuery.isComplete()); - assertEquals(messagesPerPage, mamQuery.getMessageCount()); + assertFalse(mamQuery.isComplete(), "Expected the first MAM response received by " + conTwo.getUser() + " to NOT be complete (but it was)."); + assertEquals(messagesPerPage, mamQuery.getMessageCount(), "Unexpected message count in MAM response received by " + conTwo.getUser()); List> pages = new ArrayList<>(numPages); pages.add(mamQuery.getMessages()); @@ -187,12 +187,12 @@ public class MamIntegrationTest extends AbstractSmackIntegrationTest { boolean isLastQuery = additionalPageRequestNum == numPages - 2; if (isLastQuery) { - assertTrue(mamQuery.isComplete()); + assertTrue(mamQuery.isComplete(), "Expected the last MAM response received by " + conTwo.getUser() + " to be complete (but it was not)."); } else { - assertFalse(mamQuery.isComplete()); + assertFalse(mamQuery.isComplete(), "Expected an intermediate MAM response received by " + conTwo.getUser() + " to NOT be complete (but it was)."); } - assertEquals(messagesPerPage, page.size()); + assertEquals(messagesPerPage, page.size(), "Unexpected amount of messages in the MAM response page received by " + conTwo.getUser()); pages.add(page); } @@ -202,13 +202,13 @@ public class MamIntegrationTest extends AbstractSmackIntegrationTest { queriedMessages.addAll(messages); } - assertEquals(outgoingMessages.size(), queriedMessages.size()); + assertEquals(outgoingMessages.size(), queriedMessages.size(), "An unexpected total number of messages was received through MAM by " + conTwo.getUser()); for (int i = 0; i < outgoingMessages.size(); i++) { Message outgoingMessage = outgoingMessages.get(i); Message queriedMessage = queriedMessages.get(i); - assertEquals(outgoingMessage.getBody(), queriedMessage.getBody()); + assertEquals(outgoingMessage.getBody(), queriedMessage.getBody(), "Unexpected message body for message number " + (i + 1) + " as received by " + conTwo.getUser() + " (are messages received out of order?)"); } } } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/mood/MoodIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/mood/MoodIntegrationTest.java index bdfaa520e..ca30cbca2 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/mood/MoodIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/mood/MoodIntegrationTest.java @@ -16,8 +16,6 @@ */ package org.jivesoftware.smackx.mood; -import java.util.concurrent.TimeoutException; - import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; @@ -33,7 +31,6 @@ import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.IntegrationTestRosterUtil; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; -import org.junit.jupiter.api.Assertions; @SpecificationReference(document = "XEP-0107") public class MoodIntegrationTest extends AbstractSmackIntegrationTest { @@ -82,11 +79,7 @@ public class MoodIntegrationTest extends AbstractSmackIntegrationTest { mm1.setMood(data); // for the purpose of this test, this needs not be blocking/use publishAndWait(); // Wait for the data to be received. - try { - moodReceived.waitForResult(timeout); - } catch (TimeoutException e) { - Assertions.fail("Expected to receive a PEP notification, but did not."); - } + assertResult(moodReceived, "Expected " + conTwo.getUser() + " to receive a PEP notification, but did not."); } finally { unregisterListener(mm2, moodListener); } @@ -121,14 +114,7 @@ public class MoodIntegrationTest extends AbstractSmackIntegrationTest { registerListenerAndWait(mm2, ServiceDiscoveryManager.getInstanceFor(conTwo), moodListener); // Wait for the data to be received. - try { - Object result = moodReceived.waitForResult(timeout); - - // Explicitly assert the success case. - Assertions.assertNotNull(result, "Expected to receive a PEP notification, but did not."); - } catch (TimeoutException e) { - Assertions.fail("Expected to receive a PEP notification, but did not."); - } + assertResult(moodReceived, "Expected " + conTwo.getUser() + " to receive a PEP notification, but did not."); } finally { unregisterListener(mm2, moodListener); } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java index edf71b0a2..7af0f686f 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java @@ -35,6 +35,7 @@ import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; import org.igniterealtime.smack.inttest.annotations.SpecificationReference; +import org.jxmpp.jid.DomainBareJid; import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityFullJid; import org.jxmpp.jid.parts.Resourcepart; @@ -58,9 +59,10 @@ public class MultiUserChatEntityIntegrationTest extends AbstractMultiUserChatInt "sends a service discovery information (\"disco#info\") query to the MUC service's JID. The service MUST " + "return its identity and the features it supports.") public void mucTestForDiscoveringFeatures() throws Exception { - DiscoverInfo info = mucManagerOne.getMucServiceDiscoInfo(mucManagerOne.getMucServiceDomains().get(0)); - assertTrue(info.getIdentities().size() > 0); - assertTrue(info.getFeatures().size() > 0); + final DomainBareJid mucServiceAddress = mucManagerOne.getMucServiceDomains().get(0); + DiscoverInfo info = mucManagerOne.getMucServiceDiscoInfo(mucServiceAddress); + assertFalse(info.getIdentities().isEmpty(), "Expected the service discovery information for service " + mucServiceAddress + " to include identities (but it did not)."); + assertFalse(info.getFeatures().isEmpty(), "Expected the service discovery information for service " + mucServiceAddress + " to include features (but it did not)."); } /** @@ -91,8 +93,8 @@ public class MultiUserChatEntityIntegrationTest extends AbstractMultiUserChatInt tryDestroy(mucAsSeenByTwo); } - assertTrue(rooms.containsKey(mucAddressPublic)); - assertFalse(rooms.containsKey(mucAddressHidden)); + assertTrue(rooms.containsKey(mucAddressPublic), "Expected the disco response from " + mucService + " to include the public room " + mucAddressPublic + " (but it did not)."); + assertFalse(rooms.containsKey(mucAddressHidden), "Expected the disco response from " + mucService + " to not include the hidden room " + mucAddressHidden + " (but it did)."); } /** @@ -116,8 +118,8 @@ public class MultiUserChatEntityIntegrationTest extends AbstractMultiUserChatInt tryDestroy(mucAsSeenByOne); } - assertTrue(discoInfo.getIdentities().size() > 0); - assertTrue(discoInfo.getFeatures().size() > 0); + assertFalse(discoInfo.getIdentities().isEmpty(), "Expected the service discovery information for room " + mucAddress + " to include identities (but it did not)."); + assertFalse(discoInfo.getFeatures().isEmpty(), "Expected the service discovery information for room " + mucAddress + " to include features (but it did not)."); } /** @@ -141,7 +143,7 @@ public class MultiUserChatEntityIntegrationTest extends AbstractMultiUserChatInt tryDestroy(mucAsSeenByOne); } - assertEquals(1, roomItems.getItems().size()); + assertEquals(1, roomItems.getItems().size(), "Unexpected amount of disco items for " + mucAddress); } /** @@ -168,7 +170,8 @@ public class MultiUserChatEntityIntegrationTest extends AbstractMultiUserChatInt XMPPException.XMPPErrorException xe; try { xe = assertThrows(XMPPException.XMPPErrorException.class, - () -> ServiceDiscoveryManager.getInstanceFor(conTwo).discoverItems(mucAsSeenByOneUserJid)); + () -> ServiceDiscoveryManager.getInstanceFor(conTwo).discoverItems(mucAsSeenByOneUserJid), + "Expected an XMPP error when " + conTwo.getUser() + " was trying to discover items of " + mucAsSeenByOneUserJid); } finally { tryDestroy(mucAsSeenByOne); } @@ -182,6 +185,7 @@ public class MultiUserChatEntityIntegrationTest extends AbstractMultiUserChatInt expectedCondition = StanzaError.Condition.not_acceptable; break; } - assertEquals(xe.getStanzaError().getCondition(), expectedCondition); + assertEquals(xe.getStanzaError().getCondition(), expectedCondition, + "Unexpected error condition in error returned when " + conTwo.getUser() + " was trying to discover items of " + mucAsSeenByOneUserJid); } } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java index c6e4e9209..930bbaf00 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java @@ -35,7 +35,6 @@ import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; import org.igniterealtime.smack.inttest.annotations.SpecificationReference; -import org.igniterealtime.smack.inttest.util.ResultSyncPoint; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.parts.Resourcepart; @@ -66,10 +65,10 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati MUCUser mucUser = MUCUser.from(reflectedJoinPresence); - assertNotNull(mucUser); - assertTrue(mucUser.getStatus().contains(MUCUser.Status.PRESENCE_TO_SELF_110)); - assertEquals(mucAddress + "/nick-one", reflectedJoinPresence.getFrom().toString()); - assertEquals(conOne.getUser().asEntityFullJidIfPossible().toString(), reflectedJoinPresence.getTo().toString()); + assertNotNull(mucUser, "Expected, but unable, to create a MUCUser instance from reflected join presence: " + reflectedJoinPresence); + assertTrue(mucUser.getStatus().contains(MUCUser.Status.PRESENCE_TO_SELF_110), "Expected the reflected join presence of " + conOne.getUser() + " of room " + mucAddress + " to include 'presence-to-self' (" + MUCUser.Status.PRESENCE_TO_SELF_110 + ") but it did not."); + assertEquals(mucAddress + "/nick-one", reflectedJoinPresence.getFrom().toString(), "Unexpected 'from' attribute value in the reflected join presence of " + conOne.getUser() + " of room " + mucAddress); + assertEquals(conOne.getUser().asEntityFullJidIfPossible().toString(), reflectedJoinPresence.getTo().toString(), "Unexpected 'to' attribute value in the reflected join presence of " + conOne.getUser() + " of room " + mucAddress); } finally { tryDestroy(muc); } @@ -94,11 +93,11 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati Presence reflectedLeavePresence = muc.leave(); MUCUser mucUser = MUCUser.from(reflectedLeavePresence); - assertNotNull(mucUser); + assertNotNull(mucUser, "Expected, but unable, to create a MUCUser instance from reflected leave presence: " + reflectedLeavePresence); - assertTrue(mucUser.getStatus().contains(MUCUser.Status.PRESENCE_TO_SELF_110)); - assertEquals(mucAddress + "/nick-one", reflectedLeavePresence.getFrom().toString()); - assertEquals(conOne.getUser().asEntityFullJidIfPossible().toString(), reflectedLeavePresence.getTo().toString()); + assertTrue(mucUser.getStatus().contains(MUCUser.Status.PRESENCE_TO_SELF_110), "Expected the reflected leave presence of " + conOne.getUser() + " of room " + mucAddress + " to include 'presence-to-self' (" + MUCUser.Status.PRESENCE_TO_SELF_110 + ") but it did not."); + assertEquals(mucAddress + "/nick-one", reflectedLeavePresence.getFrom().toString(), "Unexpected 'from' attribute value in the reflected leave presence of " + conOne.getUser() + " of room " + mucAddress); + assertEquals(conOne.getUser().asEntityFullJidIfPossible().toString(), reflectedLeavePresence.getTo().toString(), "Unexpected 'to' attribute value in the reflected leave presence of " + conOne.getUser() + " of room " + mucAddress); } finally { muc.join(Resourcepart.from("nick-one")); // We need to be in the room to destroy the room tryDestroy(muc); @@ -113,14 +112,14 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); final String mucMessage = "Smack Integration Test MUC Test Message " + randomString; - final ResultSyncPoint resultSyncPoint = new ResultSyncPoint<>(); + final SimpleResultSyncPoint resultSyncPoint = new SimpleResultSyncPoint(); mucAsSeenByTwo.addMessageListener(new MessageListener() { @Override public void processMessage(Message message) { String body = message.getBody(); if (mucMessage.equals(body)) { - resultSyncPoint.signal(body); + resultSyncPoint.signal(); } } }); @@ -128,10 +127,9 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati createMuc(mucAsSeenByOne, "one-" + randomString); mucAsSeenByTwo.join(Resourcepart.from("two-" + randomString)); mucAsSeenByOne.sendMessage(mucMessage); + try { - resultSyncPoint.waitForResult(timeout); - } catch (TimeoutException e) { - throw new AssertionError("Failed to receive presence", e); + assertResult(resultSyncPoint, "Expected " + conTwo.getUser() + " to receive message that was sent by " + conOne.getUser() + " in room " + mucAddress + " (but it did not)."); } finally { tryDestroy(mucAsSeenByOne); } @@ -166,19 +164,20 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati muc.addUserStatusListener(userStatusListener); - assertEquals(1, mucManagerOne.getJoinedRooms().size()); - assertEquals(1, muc.getOccupantsCount()); - assertNotNull(muc.getNickname()); + // These would be a test implementation bug, not assertion failure. + if (mucManagerOne.getJoinedRooms().size() != 1) { + throw new IllegalStateException("Expected user to have joined a room."); + } try { muc.destroy("Dummy reason", null); - mucDestroyed.waitForResult(timeout); + assertResult(mucDestroyed, "Expected " + conOne.getUser() + " to be notified of destruction of room " + mucAddress + " (but was not)."); } finally { muc.removeUserStatusListener(userStatusListener); } - assertEquals(0, mucManagerOne.getJoinedRooms().size()); - assertEquals(0, muc.getOccupantsCount()); + assertEquals(0, mucManagerOne.getJoinedRooms().size(), "Expected " + conOne.getUser() + " to no longer be in any rooms after " + mucAddress + " was destroyed (but was)."); + assertEquals(0, muc.getOccupantsCount(), "Expected room " + mucAddress + " to no longer have any occupants after it was destroyed (but it has)."); assertNull(muc.getNickname()); } } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatLowLevelIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatLowLevelIntegrationTest.java index 7cc418b2c..e77bc40cc 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatLowLevelIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatLowLevelIntegrationTest.java @@ -85,7 +85,7 @@ public class MultiUserChatLowLevelIntegrationTest extends AbstractSmackLowLevelI // So we trigger it manually here. MucBookmarkAutojoinManager.getInstanceFor(connection).autojoinBookmarkedConferences(); - assertTrue(muc.isJoined()); + assertTrue(muc.isJoined(), "Expected " + connection.getUser() + " to automatically join room " + muc.getRoom() + " after a reconnect, but it did not."); // If the test went well, leave the MUC muc.leave(); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java index b4259bae1..d171ecabb 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java @@ -23,6 +23,9 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import java.util.concurrent.TimeoutException; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; @@ -34,6 +37,7 @@ import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.ResultSyncPoint; +import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityFullJid; import org.jxmpp.jid.Jid; @@ -65,12 +69,12 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); - final ResultSyncPoint resultSyncPoint = new ResultSyncPoint<>(); + final SimpleResultSyncPoint resultSyncPoint = new SimpleResultSyncPoint(); mucAsSeenByTwo.addUserStatusListener(new UserStatusListener() { @Override public void moderatorGranted() { - resultSyncPoint.signal("done"); + resultSyncPoint.signal(); } }); @@ -83,7 +87,7 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs // success" in §9.6, since it'll throw on either an error IQ or on no response. mucAsSeenByOne.grantModerator(nicknameTwo); - resultSyncPoint.waitForResult(timeout); + assertResult(resultSyncPoint, "Expected " + conTwo.getUser() + " to get a presence update after it was granted the role 'moderator' role in " + mucAddress + " (but it did not)."); } finally { tryDestroy(mucAsSeenByOne); } @@ -105,12 +109,12 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); MultiUserChat mucAsSeenByThree = mucManagerThree.getMultiUserChat(mucAddress); - final ResultSyncPoint resultSyncPoint = new ResultSyncPoint<>(); + final SimpleResultSyncPoint resultSyncPoint = new SimpleResultSyncPoint(); mucAsSeenByThree.addParticipantStatusListener(new ParticipantStatusListener() { @Override public void moderatorGranted(EntityFullJid participant) { - resultSyncPoint.signal("done"); + resultSyncPoint.signal(); } }); @@ -122,7 +126,8 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs mucAsSeenByThree.join(nicknameThree); mucAsSeenByOne.grantModerator(nicknameTwo); - resultSyncPoint.waitForResult(timeout); + + assertResult(resultSyncPoint, "Expected " + conThree.getUser() + " to get a presence update after another user in the room was granted the 'moderator' role in " + mucAddress + " (but it did not)."); } finally { tryDestroy(mucAsSeenByOne); } @@ -144,12 +149,12 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); - final ResultSyncPoint resultSyncPoint = new ResultSyncPoint<>(); + final SimpleResultSyncPoint resultSyncPoint = new SimpleResultSyncPoint(); mucAsSeenByTwo.addUserStatusListener(new UserStatusListener() { @Override public void moderatorRevoked() { - resultSyncPoint.signal("done"); + resultSyncPoint.signal(); } }); @@ -160,7 +165,8 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs mucAsSeenByOne.grantModerator(nicknameTwo); mucAsSeenByOne.revokeModerator(nicknameTwo); - resultSyncPoint.waitForResult(timeout); + + assertResult(resultSyncPoint, "Expected " + conTwo.getUser() + " to get a presence update after its 'moderator' role in " + mucAddress + " was revoked (but it did not)."); } finally { tryDestroy(mucAsSeenByOne); } @@ -182,12 +188,12 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); MultiUserChat mucAsSeenByThree = mucManagerThree.getMultiUserChat(mucAddress); - final ResultSyncPoint resultSyncPoint = new ResultSyncPoint<>(); + final SimpleResultSyncPoint resultSyncPoint = new SimpleResultSyncPoint(); mucAsSeenByThree.addParticipantStatusListener(new ParticipantStatusListener() { @Override public void moderatorRevoked(EntityFullJid participant) { - resultSyncPoint.signal("done"); + resultSyncPoint.signal(); } }); @@ -200,7 +206,7 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs mucAsSeenByOne.grantModerator(nicknameTwo); mucAsSeenByOne.revokeModerator(nicknameTwo); - resultSyncPoint.waitForResult(timeout); + assertResult(resultSyncPoint, "Expected " + conThree.getUser() + " to get a presence update after the 'moderator' role of another user in the room was revoked in " + mucAddress + " (but it did not)."); } finally { tryDestroy(mucAsSeenByOne); } @@ -221,12 +227,12 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); - final ResultSyncPoint resultSyncPoint = new ResultSyncPoint<>(); + final SimpleResultSyncPoint resultSyncPoint = new SimpleResultSyncPoint(); mucAsSeenByTwo.addUserStatusListener(new UserStatusListener() { @Override public void voiceRevoked() { - resultSyncPoint.signal("done"); + resultSyncPoint.signal(); } }); @@ -235,7 +241,7 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); mucAsSeenByTwo.join(nicknameTwo); mucAsSeenByOne.revokeVoice(nicknameTwo); - resultSyncPoint.waitForResult(timeout); + assertResult(resultSyncPoint, "Expected " + conTwo.getUser() + " to get a presence update after its 'voice' privilege was revoked in " + mucAddress + " (but it did not)."); } finally { tryDestroy(mucAsSeenByOne); } @@ -257,12 +263,12 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); MultiUserChat mucAsSeenByThree = mucManagerThree.getMultiUserChat(mucAddress); - final ResultSyncPoint resultSyncPoint = new ResultSyncPoint<>(); + final SimpleResultSyncPoint resultSyncPoint = new SimpleResultSyncPoint(); mucAsSeenByThree.addParticipantStatusListener(new ParticipantStatusListener() { @Override public void voiceRevoked(EntityFullJid participant) { - resultSyncPoint.signal("done"); + resultSyncPoint.signal(); } }); @@ -274,7 +280,7 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs mucAsSeenByThree.join(nicknameThree); mucAsSeenByOne.revokeVoice(nicknameTwo); - resultSyncPoint.waitForResult(timeout); + assertResult(resultSyncPoint, "Expected " + conThree.getUser() + " to get a presence update after another user's 'voice' privilege was revoked in " + mucAddress + " (but it did not)."); } finally { tryDestroy(mucAsSeenByOne); } @@ -295,13 +301,13 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); - final ResultSyncPoint resultSyncPoint = new ResultSyncPoint<>(); + final SimpleResultSyncPoint resultSyncPoint = new SimpleResultSyncPoint(); mucAsSeenByTwo.addUserStatusListener(new UserStatusListener() { @Override public void adminGranted() { - resultSyncPoint.signal("done"); + resultSyncPoint.signal(); } }); @@ -312,7 +318,7 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs // This implicitly tests "The service MUST add the user to the admin list and then inform the owner of success" in §10.6, since it'll throw on either an error IQ or on no response. mucAsSeenByOne.grantAdmin(conTwo.getUser().asBareJid()); - resultSyncPoint.waitForResult(timeout); + assertResult(resultSyncPoint, "Expected " + conTwo.getUser() + " to get a presence update after its was granted 'admin' affiliation in " + mucAddress + " (but it did not)."); } finally { tryDestroy(mucAsSeenByOne); } @@ -335,12 +341,12 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); MultiUserChat mucAsSeenByThree = mucManagerThree.getMultiUserChat(mucAddress); - final ResultSyncPoint resultSyncPoint = new ResultSyncPoint<>(); + final SimpleResultSyncPoint resultSyncPoint = new SimpleResultSyncPoint(); mucAsSeenByThree.addParticipantStatusListener(new ParticipantStatusListener() { @Override public void adminGranted(EntityFullJid participant) { - resultSyncPoint.signal("done"); + resultSyncPoint.signal(); } }); @@ -352,7 +358,7 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs mucAsSeenByThree.join(nicknameThree); mucAsSeenByOne.grantAdmin(conTwo.getUser().asBareJid()); - resultSyncPoint.waitForResult(timeout); + assertResult(resultSyncPoint, "Expected " + conThree.getUser() + " to get a presence update after another user was granted 'admin' affiliation in " + mucAddress + " (but it did not)."); } finally { tryDestroy(mucAsSeenByOne); } @@ -374,12 +380,12 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); - final ResultSyncPoint resultSyncPoint = new ResultSyncPoint<>(); + final SimpleResultSyncPoint resultSyncPoint = new SimpleResultSyncPoint(); mucAsSeenByTwo.addUserStatusListener(new UserStatusListener() { @Override public void adminRevoked() { - resultSyncPoint.signal("done"); + resultSyncPoint.signal(); } }); @@ -390,7 +396,7 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs mucAsSeenByOne.grantAdmin(conTwo.getUser().asBareJid()); mucAsSeenByOne.revokeAdmin(conTwo.getUser().asEntityBareJid()); - resultSyncPoint.waitForResult(timeout); + assertResult(resultSyncPoint, "Expected " + conTwo.getUser() + " to get a presence update after its 'admin' affiliation was revoked in " + mucAddress + " (but it did not)."); } finally { tryDestroy(mucAsSeenByOne); } @@ -425,12 +431,12 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); MultiUserChat mucAsSeenByThree = mucManagerThree.getMultiUserChat(mucAddress); - final ResultSyncPoint resultSyncPoint = new ResultSyncPoint<>(); + final SimpleResultSyncPoint resultSyncPoint = new SimpleResultSyncPoint(); mucAsSeenByThree.addParticipantStatusListener(new ParticipantStatusListener() { @Override public void adminRevoked(EntityFullJid participant) { - resultSyncPoint.signal("done"); + resultSyncPoint.signal(); } }); @@ -443,7 +449,7 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs mucAsSeenByOne.grantAdmin(conTwo.getUser().asBareJid()); mucAsSeenByOne.revokeAdmin(conTwo.getUser().asEntityBareJid()); - resultSyncPoint.waitForResult(timeout); + assertResult(resultSyncPoint, "Expected " + conThree.getUser() + " to get a presence update after another user's 'admin' affiliation was revoked in " + mucAddress + " (but it did not)."); } finally { tryDestroy(mucAsSeenByOne); } @@ -477,16 +483,18 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs mucAsSeenByOne.kickParticipant(nicknameTwo, "Nothing personal. Just a test."); Presence kickPresence = resultSyncPoint.waitForResult(timeout); MUCUser mucUser = MUCUser.from(kickPresence); - assertNotNull(mucUser); + assertNotNull(mucUser, "Expected, but unable, to create a MUCUser instance from 'kick' presence: " + kickPresence); assertAll( - () -> assertTrue(mucUser.getStatus().contains(MUCUser.Status.PRESENCE_TO_SELF_110), "Missing self-presence status code in kick presence"), - () -> assertTrue(mucUser.getStatus().contains(MUCUser.Status.KICKED_307), "Missing kick status code in kick presence"), - () -> assertEquals(MUCRole.none, mucUser.getItem().getRole(), "Role other than 'none' in kick presence") + () -> assertTrue(mucUser.getStatus().contains(MUCUser.Status.PRESENCE_TO_SELF_110), "Missing self-presence status code in kick presence received by " + conTwo.getUser() + " after being kicked from room " + mucAddress), + () -> assertTrue(mucUser.getStatus().contains(MUCUser.Status.KICKED_307), "Missing kick status code in kick presence received by " + conTwo.getUser() + " after being kicked from room " + mucAddress), + () -> assertEquals(MUCRole.none, mucUser.getItem().getRole(), "Role other than 'none' in kick presence received by " + conTwo.getUser() + " after being kicked from room " + mucAddress) ); Jid itemJid = mucUser.getItem().getJid(); if (itemJid != null) { - assertEquals(conTwo.getUser().asEntityFullJidIfPossible(), itemJid, "Incorrect kicked user in kick presence"); + assertEquals(conTwo.getUser().asEntityFullJidIfPossible(), itemJid, "Incorrect kicked user in kick presence received by " + conTwo.getUser() + " after being kicked from room " + mucAddress); } + } catch (TimeoutException e) { + fail("Expected " + conTwo.getUser() + " to receive a presence update after it was kicked from room " + mucAddress + " (but it did not).", e); } finally { tryDestroy(mucAsSeenByOne); } @@ -522,16 +530,18 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs mucAsSeenByOne.kickParticipant(nicknameTwo, "Nothing personal. Just a test."); Presence kickPresence = resultSyncPoint.waitForResult(timeout); MUCUser mucUser = MUCUser.from(kickPresence); - assertNotNull(mucUser); + assertNotNull(mucUser, "Expected, but unable, to create a MUCUser instance from 'kick' presence: " + kickPresence); assertAll( - () -> assertFalse(mucUser.getStatus().contains(MUCUser.Status.PRESENCE_TO_SELF_110), "Incorrect self-presence status code in kick presence"), - () -> assertTrue(mucUser.getStatus().contains(MUCUser.Status.KICKED_307), "Missing kick status code in kick presence"), - () -> assertEquals(MUCRole.none, mucUser.getItem().getRole(), "Role other than 'none' in kick presence") + () -> assertFalse(mucUser.getStatus().contains(MUCUser.Status.PRESENCE_TO_SELF_110), "Incorrect self-presence status code in kick presence received by " + conThree.getUser() + " after another user was kicked from room " + mucAddress), + () -> assertTrue(mucUser.getStatus().contains(MUCUser.Status.KICKED_307), "Missing kick status code in kick presence received by " + conThree.getUser() + " after another user was kicked from room " + mucAddress), + () -> assertEquals(MUCRole.none, mucUser.getItem().getRole(), "Role other than 'none' in kick presence received by " + conThree.getUser() + " after another user was kicked from room " + mucAddress) ); Jid itemJid = mucUser.getItem().getJid(); if (itemJid != null) { - assertEquals(conTwo.getUser().asEntityFullJidIfPossible(), itemJid, "Incorrect kicked user in kick presence"); + assertEquals(conTwo.getUser().asEntityFullJidIfPossible(), itemJid, "Incorrect kicked user in kick presence received by " + conThree.getUser() + " after another user was kicked from room " + mucAddress); } + } catch (TimeoutException e) { + fail("Expected " + conThree.getUser() + " to receive a presence update after another user was kicked from room " + mucAddress + " (but it did not).", e); } finally { tryDestroy(mucAsSeenByOne); } @@ -570,8 +580,8 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs mucAsSeenByThree.leave(); Presence p2 = mucAsSeenByTwo.join(nicknameTwo); Presence p3 = mucAsSeenByThree.join(nicknameThree); - assertEquals(MUCAffiliation.owner, MUCUser.from(p2).getItem().getAffiliation()); - assertEquals(MUCAffiliation.admin, MUCUser.from(p3).getItem().getAffiliation()); + assertEquals(MUCAffiliation.owner, MUCUser.from(p2).getItem().getAffiliation(), "Unexpected affiliation of " + conTwo.getUser() + " after it re-joined room " + mucAddress); + assertEquals(MUCAffiliation.admin, MUCUser.from(p3).getItem().getAffiliation(), "Unexpected affiliation of " + conThree.getUser() + " after it re-joined room " + mucAddress); } finally { tryDestroy(mucAsSeenByOne); } @@ -602,8 +612,9 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs mucAsSeenByTwo.join(nicknameTwo); mucAsSeenByOne.grantModerator(nicknameTwo); XMPPException.XMPPErrorException xe = assertThrows(XMPPException.XMPPErrorException.class, - () -> mucAsSeenByTwo.revokeVoice(nicknameOne)); - assertEquals(xe.getStanzaError().getCondition().toString(), "not-allowed"); + () -> mucAsSeenByTwo.revokeVoice(nicknameOne), + "Expected an XMPP error when " + conTwo.getUser() + " was trying to revoke the 'voice' privilege of " + conOne.getUser() + " in room " + mucAddress); + assertEquals(xe.getStanzaError().getCondition().toString(), "not-allowed", "Unexpected stanza error condition in error returned when " + conTwo.getUser() + " was trying to revoke the 'voice' privilege of " + conOne.getUser() + " in room " + mucAddress); } finally { tryDestroy(mucAsSeenByOne); } @@ -640,16 +651,19 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs // Admin cannot revoke from Owner XMPPException.XMPPErrorException xe1 = assertThrows(XMPPException.XMPPErrorException.class, - () -> mucAsSeenByTwo.revokeModerator(nicknameOne)); - // Moderator cannot revoke from Admin - XMPPException.XMPPErrorException xe2 = assertThrows(XMPPException.XMPPErrorException.class, - () -> mucAsSeenByThree.revokeModerator(nicknameOne)); + () -> mucAsSeenByTwo.revokeModerator(nicknameOne), + "Expected an XMPP error when " + conTwo.getUser() + " (an admin) was trying to revoke the 'moderator' role of " + conOne.getUser() + " (an owner) in room " + mucAddress); // Moderator cannot revoke from Owner + XMPPException.XMPPErrorException xe2 = assertThrows(XMPPException.XMPPErrorException.class, + () -> mucAsSeenByThree.revokeModerator(nicknameOne), + "Expected an XMPP error when " + conThree.getUser() + " (a moderator) was trying to revoke the 'moderator' role of " + conOne.getUser() + " (an owner) in room " + mucAddress); + // Moderator cannot revoke from Admin XMPPException.XMPPErrorException xe3 = assertThrows(XMPPException.XMPPErrorException.class, - () -> mucAsSeenByThree.revokeModerator(nicknameTwo)); - assertEquals(xe1.getStanzaError().getCondition().toString(), "not-allowed"); - assertEquals(xe2.getStanzaError().getCondition().toString(), "not-allowed"); - assertEquals(xe3.getStanzaError().getCondition().toString(), "not-allowed"); + () -> mucAsSeenByThree.revokeModerator(nicknameTwo), + "Expected an XMPP error when " + conThree.getUser() + " (a moderator) was trying to revoke the 'moderator' role of " + conTwo.getUser() + " (an admin) in room " + mucAddress); + assertEquals(xe1.getStanzaError().getCondition().toString(), "not-allowed", "Unexpected condition in XMPP error when " + conTwo.getUser() + " (an admin) was trying to revoke the 'moderator' role of " + conOne.getUser() + " (an owner) in room " + mucAddress); + assertEquals(xe2.getStanzaError().getCondition().toString(), "not-allowed", "Unexpected condition in XMPP error when " + conThree.getUser() + " (a moderator) was trying to revoke the 'moderator' role of " + conOne.getUser() + " (an owner) in room " + mucAddress); + assertEquals(xe3.getStanzaError().getCondition().toString(), "not-allowed", "Unexpected condition in XMPP error when " + conThree.getUser() + " (a moderator) was trying to revoke the 'moderator' role of " + conTwo.getUser() + " (an admin) in room " + mucAddress); } finally { tryDestroy(mucAsSeenByOne); } @@ -678,23 +692,23 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs mucAsSeenByTwo.join(nicknameTwo); mucAsSeenByThree.join(nicknameThree); - final ResultSyncPoint resultSyncPoint = new ResultSyncPoint<>(); + final SimpleResultSyncPoint resultSyncPoint = new SimpleResultSyncPoint(); mucAsSeenByOne.addParticipantStatusListener(new ParticipantStatusListener() { @Override public void adminGranted(EntityFullJid participant) { - resultSyncPoint.signal("done"); + resultSyncPoint.signal(); } }); mucAsSeenByOne.grantAdmin(conTwo.getUser().asBareJid()); resultSyncPoint.waitForResult(timeout); - assertEquals(mucAsSeenByOne.getOccupantsCount(), 3); - assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant( - JidCreate.entityFullFrom(mucAddress, nicknameOne)).getRole()); - assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant( - JidCreate.entityFullFrom(mucAddress, nicknameTwo)).getRole()); - assertEquals(MUCRole.participant, mucAsSeenByOne.getOccupant( - JidCreate.entityFullFrom(mucAddress, nicknameThree)).getRole()); + assertEquals(mucAsSeenByOne.getOccupantsCount(), 3, "Unexpected occupant count in room " + mucAddress); + assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant(JidCreate.entityFullFrom(mucAddress, nicknameOne)).getRole(), + "Unexpected role for occupant " + nicknameOne + " of " + mucAddress); + assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant(JidCreate.entityFullFrom(mucAddress, nicknameTwo)).getRole(), + "Unexpected role for occupant " + nicknameTwo + " of " + mucAddress); + assertEquals(MUCRole.participant, mucAsSeenByOne.getOccupant(JidCreate.entityFullFrom(mucAddress, nicknameThree)).getRole(), + "Unexpected role for occupant " + nicknameThree + " of " + mucAddress); } finally { tryDestroy(mucAsSeenByOne); } @@ -718,11 +732,11 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); final Resourcepart nicknameThree = Resourcepart.from("three-" + randomString); - final ResultSyncPoint resultSyncPoint = new ResultSyncPoint<>(); + final SimpleResultSyncPoint resultSyncPoint = new SimpleResultSyncPoint(); mucAsSeenByOne.addParticipantStatusListener(new ParticipantStatusListener() { @Override public void adminGranted(EntityFullJid participant) { - resultSyncPoint.signal("done"); + resultSyncPoint.signal(); } }); @@ -744,13 +758,13 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs mucAsSeenByOne.grantAdmin(conTwo.getUser().asBareJid()); resultSyncPoint.waitForResult(timeout); - assertEquals(mucAsSeenByOne.getOccupantsCount(), 3); - assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant( - JidCreate.entityFullFrom(mucAddress, nicknameOne)).getRole()); - assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant( - JidCreate.entityFullFrom(mucAddress, nicknameTwo)).getRole()); - assertEquals(threeRole, mucAsSeenByOne.getOccupant( - JidCreate.entityFullFrom(mucAddress, nicknameThree)).getRole()); + assertEquals(mucAsSeenByOne.getOccupantsCount(), 3, "Unexpected occupant count in room " + mucAddress); + assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant(JidCreate.entityFullFrom(mucAddress, nicknameOne)).getRole(), + "Unexpected role for occupant " + nicknameOne + " of " + mucAddress); + assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant(JidCreate.entityFullFrom(mucAddress, nicknameTwo)).getRole(), + "Unexpected role for occupant " + nicknameTwo + " of " + mucAddress); + assertEquals(threeRole, mucAsSeenByOne.getOccupant(JidCreate.entityFullFrom(mucAddress, nicknameThree)).getRole(), + "Unexpected role for occupant " + nicknameThree + " of " + mucAddress); } finally { tryDestroy(mucAsSeenByOne); } @@ -780,11 +794,11 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs createMembersOnlyMuc(mucAsSeenByOne, nicknameOne); - final ResultSyncPoint adminResultSyncPoint = new ResultSyncPoint<>(); + final SimpleResultSyncPoint adminResultSyncPoint = new SimpleResultSyncPoint(); mucAsSeenByOne.addParticipantStatusListener(new ParticipantStatusListener() { @Override public void adminGranted(EntityFullJid participant) { - adminResultSyncPoint.signal("done"); + adminResultSyncPoint.signal(); } }); @@ -796,10 +810,10 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs mucAsSeenByThree.join(nicknameThree); mucAsSeenByOne.grantAdmin(conTwo.getUser().asBareJid()); adminResultSyncPoint.waitForResult(timeout); - assertEquals(mucAsSeenByOne.getOccupantsCount(), 3); - assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant(jidOne).getRole()); - assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant(jidTwo).getRole()); - assertEquals(MUCRole.participant, mucAsSeenByOne.getOccupant(jidThree).getRole()); + assertEquals(mucAsSeenByOne.getOccupantsCount(), 3, "Unexpected occupant count in room " + mucAddress); + assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant(jidOne).getRole(), "Unexpected role for occupant " + jidOne + " in room " + mucAddress); + assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant(jidTwo).getRole(), "Unexpected role for occupant " + jidTwo + " in room " + mucAddress); + assertEquals(MUCRole.participant, mucAsSeenByOne.getOccupant(jidThree).getRole(), "Unexpected role for occupant " + jidThree + " in room " + mucAddress); } finally { tryDestroy(mucAsSeenByOne); } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/AbstractTwoUsersOmemoIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/AbstractTwoUsersOmemoIntegrationTest.java index 1720c0725..995fc14a8 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/AbstractTwoUsersOmemoIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/AbstractTwoUsersOmemoIntegrationTest.java @@ -17,7 +17,7 @@ package org.jivesoftware.smackx.omemo; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import java.io.IOException; @@ -51,7 +51,9 @@ public abstract class AbstractTwoUsersOmemoIntegrationTest extends AbstractOmemo alice = OmemoManagerSetupHelper.prepareOmemoManager(conOne); bob = OmemoManagerSetupHelper.prepareOmemoManager(conTwo); - assertFalse(alice.getDeviceId().equals(bob.getDeviceId())); + // TODO is this a test assertion, or a bug in the test implementation (in which case an Exception should be thrown instead). + assertNotEquals(alice.getDeviceId(), bob.getDeviceId(), + "Expected device ID for " + conOne.getUser() + " to differ from that of " + conTwo.getUser() + " (but they did not)"); // Subscribe presences IntegrationTestRosterUtil.ensureBothAccountsAreSubscribedToEachOther(alice.getConnection(), bob.getConnection(), timeout); @@ -59,8 +61,10 @@ public abstract class AbstractTwoUsersOmemoIntegrationTest extends AbstractOmemo OmemoManagerSetupHelper.trustAllIdentitiesWithTests(alice, bob); // Alice trusts Bob's devices OmemoManagerSetupHelper.trustAllIdentitiesWithTests(bob, alice); // Bob trusts Alice' and Mallory's devices - assertEquals(bob.getOwnFingerprint(), alice.getActiveFingerprints(bob.getOwnJid()).get(bob.getOwnDevice())); - assertEquals(alice.getOwnFingerprint(), bob.getActiveFingerprints(alice.getOwnJid()).get(alice.getOwnDevice())); + assertEquals(bob.getOwnFingerprint(), alice.getActiveFingerprints(bob.getOwnJid()).get(bob.getOwnDevice()), + "Expected fingerprint of " + conTwo.getUser() + "'s device as known to " + conOne.getUser() + " to be equal to " + conTwo.getUser() + "'s own fingerprint (but it was not)."); + assertEquals(alice.getOwnFingerprint(), bob.getActiveFingerprints(alice.getOwnJid()).get(alice.getOwnDevice()), + "Expected fingerprint of " + conOne.getUser() + "'s device as known to " + conTwo.getUser() + " to be equal to " + conOne.getUser() + "'s own fingerprint (but it was not)."); } @AfterClass diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMamDecryptionTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMamDecryptionTest.java index 489dee26c..ff46adc8a 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMamDecryptionTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMamDecryptionTest.java @@ -73,11 +73,12 @@ public class OmemoMamDecryptionTest extends AbstractTwoUsersOmemoIntegrationTest alicesConnection.sendStanza(encrypted.buildMessage(messageBuilder, bob.getOwnJid())); MamManager.MamQuery query = bobsMamManager.queryArchive(MamManager.MamQueryArgs.builder().limitResultsToJid(alice.getOwnJid()).build()); - assertEquals(1, query.getMessageCount()); + assertEquals(1, query.getMessageCount(), "Unexpected message count in MAM query result of " + bob.getConnection().getUser()); List decryptedMamQuery = bob.decryptMamQueryResult(query); - assertEquals(1, decryptedMamQuery.size()); - assertEquals(body, decryptedMamQuery.get(decryptedMamQuery.size() - 1).getOmemoMessage().getBody()); + assertEquals(1, decryptedMamQuery.size(), "Unexpected decrypted message count in MAM query result of " + bob.getConnection().getUser()); + assertEquals(body, decryptedMamQuery.get(decryptedMamQuery.size() - 1).getOmemoMessage().getBody(), + "Expected decrypted body of message retrieved via a MAM query to be equal to the original body that was sent (but it was not)."); } } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/pubsub/PubSubIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/pubsub/PubSubIntegrationTest.java index 4e2377c26..a9f664f43 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/pubsub/PubSubIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/pubsub/PubSubIntegrationTest.java @@ -125,9 +125,9 @@ public class PubSubIntegrationTest extends AbstractSmackIntegrationTest { Item item = new PayloadItem<>(itemId, dummyPayload); leafNode.publish(item); - }); - assertEquals(StanzaError.Type.MODIFY, e.getStanzaError().getType()); - assertNotNull(e.getStanzaError().getExtension("item-forbidden", "http://jabber.org/protocol/pubsub#errors")); + }, "Expected an error after publishing item " + itemId + " (but none occurred)."); + assertEquals(StanzaError.Type.MODIFY, e.getStanzaError().getType(), "Unexpected error type"); + assertNotNull(e.getStanzaError().getExtension("item-forbidden", "http://jabber.org/protocol/pubsub#errors"), "Expected error to contain 'item-forbidden', but it did not."); } finally { pubSubManagerOne.deleteNode(nodename); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/softwareInfo/SoftwareInfoIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/softwareInfo/SoftwareInfoIntegrationTest.java index 64374e173..35e5547d5 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/softwareInfo/SoftwareInfoIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/softwareInfo/SoftwareInfoIntegrationTest.java @@ -64,7 +64,8 @@ public class SoftwareInfoIntegrationTest extends AbstractSmackIntegrationTest { } }); SoftwareInfoForm softwareInfoFormReceived = sim2.fromJid(conOne.getUser()); - assertEquals(softwareInfoSent, softwareInfoFormReceived); + assertEquals(softwareInfoSent, softwareInfoFormReceived, + "Expected " + conOne.getUser() + "'s software version info as received by " + conTwo.getUser() + " to be equal to what " + conOne.getUser() + " publishes (but it is not)."); } private static SoftwareInfoForm createSoftwareInfoForm() throws URISyntaxException { 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 index db3275d00..6127b80d7 100644 --- 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 @@ -17,7 +17,6 @@ package org.jivesoftware.smackx.usertune; import java.net.URI; -import java.util.concurrent.TimeoutException; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.SmackException.NotLoggedInException; @@ -140,14 +139,7 @@ public class UserTuneIntegrationTest extends AbstractSmackIntegrationTest { registerListenerAndWait(utm2, ServiceDiscoveryManager.getInstanceFor(conTwo), userTuneListener); // Wait for the data to be received. - try { - Object result = userTuneReceived.waitForResult(timeout); - - // Explicitly assert the success case. - Assertions.assertNotNull(result, "Expected to receive a PEP notification, but did not."); - } catch (TimeoutException e) { - Assertions.fail("Expected to receive a PEP notification, but did not."); - } + assertResult(userTuneReceived, "Expected " + conTwo.getUser() + " to receive a PEP notification from " + conOne.getUser() + ", but did not."); } finally { unregisterListener(utm2, userTuneListener); } From c67292ea860e55b977cad0736008c3c1301f7ce2 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Wed, 10 Apr 2024 11:40:55 +0200 Subject: [PATCH 021/150] [sinttest]: Fix order of arguments in assertEquals() When using 'assertEquals', the first argument is to be the _expected_ value, the second the _actual_ value. When this is inverted, the functional test will still succeed, but any generated error message ("Expected X, got Y") will be wrong. This commit fixes the order of arguments, mostly in the sinttest module. --- .../commands/AdHocCommandIntegrationTest.java | 2 +- .../muc/MultiUserChatEntityIntegrationTest.java | 2 +- ...RolesAffiliationsPrivilegesIntegrationTest.java | 14 +++++++------- .../org/jivesoftware/smackx/xdata/FormTest.java | 5 +++-- .../smackx/jingle/nat/STUNResolverTest.java | 4 ++-- .../smackx/jingle/nat/TransportCandidateTest.java | 2 +- 6 files changed, 15 insertions(+), 14 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandIntegrationTest.java index 521692148..3e2b55516 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandIntegrationTest.java @@ -354,7 +354,7 @@ public class AdHocCommandIntegrationTest extends AbstractSmackIntegrationTest { SubmitForm submitForm = form.getSubmitForm(); XMPPErrorException exception = assertThrows(XMPPErrorException.class, () -> command.next(submitForm)); - assertEquals(exception.getStanzaError().getCondition(), StanzaError.Condition.bad_request, + assertEquals(StanzaError.Condition.bad_request, exception.getStanzaError().getCondition(), "Unexpected error condition received after " + conTwo.getUser() + " supplied an invalid argument " + "to the command node '" + commandNode + "' of " + conOne.getUser()); } finally { diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java index 7af0f686f..30b052466 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java @@ -185,7 +185,7 @@ public class MultiUserChatEntityIntegrationTest extends AbstractMultiUserChatInt expectedCondition = StanzaError.Condition.not_acceptable; break; } - assertEquals(xe.getStanzaError().getCondition(), expectedCondition, + assertEquals(expectedCondition, xe.getStanzaError().getCondition(), "Unexpected error condition in error returned when " + conTwo.getUser() + " was trying to discover items of " + mucAsSeenByOneUserJid); } } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java index d171ecabb..f5fc7472f 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java @@ -614,7 +614,7 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs XMPPException.XMPPErrorException xe = assertThrows(XMPPException.XMPPErrorException.class, () -> mucAsSeenByTwo.revokeVoice(nicknameOne), "Expected an XMPP error when " + conTwo.getUser() + " was trying to revoke the 'voice' privilege of " + conOne.getUser() + " in room " + mucAddress); - assertEquals(xe.getStanzaError().getCondition().toString(), "not-allowed", "Unexpected stanza error condition in error returned when " + conTwo.getUser() + " was trying to revoke the 'voice' privilege of " + conOne.getUser() + " in room " + mucAddress); + assertEquals("not-allowed", xe.getStanzaError().getCondition().toString(), "Unexpected stanza error condition in error returned when " + conTwo.getUser() + " was trying to revoke the 'voice' privilege of " + conOne.getUser() + " in room " + mucAddress); } finally { tryDestroy(mucAsSeenByOne); } @@ -661,9 +661,9 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs XMPPException.XMPPErrorException xe3 = assertThrows(XMPPException.XMPPErrorException.class, () -> mucAsSeenByThree.revokeModerator(nicknameTwo), "Expected an XMPP error when " + conThree.getUser() + " (a moderator) was trying to revoke the 'moderator' role of " + conTwo.getUser() + " (an admin) in room " + mucAddress); - assertEquals(xe1.getStanzaError().getCondition().toString(), "not-allowed", "Unexpected condition in XMPP error when " + conTwo.getUser() + " (an admin) was trying to revoke the 'moderator' role of " + conOne.getUser() + " (an owner) in room " + mucAddress); - assertEquals(xe2.getStanzaError().getCondition().toString(), "not-allowed", "Unexpected condition in XMPP error when " + conThree.getUser() + " (a moderator) was trying to revoke the 'moderator' role of " + conOne.getUser() + " (an owner) in room " + mucAddress); - assertEquals(xe3.getStanzaError().getCondition().toString(), "not-allowed", "Unexpected condition in XMPP error when " + conThree.getUser() + " (a moderator) was trying to revoke the 'moderator' role of " + conTwo.getUser() + " (an admin) in room " + mucAddress); + assertEquals("not-allowed", xe1.getStanzaError().getCondition().toString(), "Unexpected condition in XMPP error when " + conTwo.getUser() + " (an admin) was trying to revoke the 'moderator' role of " + conOne.getUser() + " (an owner) in room " + mucAddress); + assertEquals("not-allowed", xe2.getStanzaError().getCondition().toString(), "Unexpected condition in XMPP error when " + conThree.getUser() + " (a moderator) was trying to revoke the 'moderator' role of " + conOne.getUser() + " (an owner) in room " + mucAddress); + assertEquals("not-allowed", xe3.getStanzaError().getCondition().toString(), "Unexpected condition in XMPP error when " + conThree.getUser() + " (a moderator) was trying to revoke the 'moderator' role of " + conTwo.getUser() + " (an admin) in room " + mucAddress); } finally { tryDestroy(mucAsSeenByOne); } @@ -702,7 +702,7 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs mucAsSeenByOne.grantAdmin(conTwo.getUser().asBareJid()); resultSyncPoint.waitForResult(timeout); - assertEquals(mucAsSeenByOne.getOccupantsCount(), 3, "Unexpected occupant count in room " + mucAddress); + assertEquals(3, mucAsSeenByOne.getOccupantsCount(), "Unexpected occupant count in room " + mucAddress); assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant(JidCreate.entityFullFrom(mucAddress, nicknameOne)).getRole(), "Unexpected role for occupant " + nicknameOne + " of " + mucAddress); assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant(JidCreate.entityFullFrom(mucAddress, nicknameTwo)).getRole(), @@ -758,7 +758,7 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs mucAsSeenByOne.grantAdmin(conTwo.getUser().asBareJid()); resultSyncPoint.waitForResult(timeout); - assertEquals(mucAsSeenByOne.getOccupantsCount(), 3, "Unexpected occupant count in room " + mucAddress); + assertEquals(3, mucAsSeenByOne.getOccupantsCount(), "Unexpected occupant count in room " + mucAddress); assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant(JidCreate.entityFullFrom(mucAddress, nicknameOne)).getRole(), "Unexpected role for occupant " + nicknameOne + " of " + mucAddress); assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant(JidCreate.entityFullFrom(mucAddress, nicknameTwo)).getRole(), @@ -810,7 +810,7 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs mucAsSeenByThree.join(nicknameThree); mucAsSeenByOne.grantAdmin(conTwo.getUser().asBareJid()); adminResultSyncPoint.waitForResult(timeout); - assertEquals(mucAsSeenByOne.getOccupantsCount(), 3, "Unexpected occupant count in room " + mucAddress); + assertEquals(3, mucAsSeenByOne.getOccupantsCount(), "Unexpected occupant count in room " + mucAddress); assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant(jidOne).getRole(), "Unexpected role for occupant " + jidOne + " in room " + mucAddress); assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant(jidTwo).getRole(), "Unexpected role for occupant " + jidTwo + " in room " + mucAddress); assertEquals(MUCRole.participant, mucAsSeenByOne.getOccupant(jidThree).getRole(), "Unexpected role for occupant " + jidThree + " in room " + mucAddress); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/xdata/FormTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/xdata/FormTest.java index 64b4db597..667beedb7 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/xdata/FormTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/xdata/FormTest.java @@ -148,8 +148,9 @@ public class FormTest extends AbstractSmackIntegrationTest { assertNotNull(completedForm2.getField("name")); assertNotNull(completedForm2.getField("description")); assertEquals( - completedForm2.getField("name").getValues().get(0).toString(), - "Credit card number invalid"); + "Credit card number invalid", + completedForm2.getField("name").getValues().get(0).toString() + ); assertNotNull(completedForm2.getField("time")); assertNotNull(completedForm2.getField("age")); assertEquals("20", completedForm2.getField("age").getValues().get(0).toString(), "The age is bad"); diff --git a/smack-jingle-old/src/integration-test/java/org/jivesoftware/smackx/jingle/nat/STUNResolverTest.java b/smack-jingle-old/src/integration-test/java/org/jivesoftware/smackx/jingle/nat/STUNResolverTest.java index 5d9425a92..febac9374 100644 --- a/smack-jingle-old/src/integration-test/java/org/jivesoftware/smackx/jingle/nat/STUNResolverTest.java +++ b/smack-jingle-old/src/integration-test/java/org/jivesoftware/smackx/jingle/nat/STUNResolverTest.java @@ -99,7 +99,7 @@ public class STUNResolverTest extends SmackTestCase { stunResolver.addCandidate(cand3); stunResolver.addCandidate(cand4); - assertEquals(stunResolver.getPreferredCandidate(), candH); + assertEquals(candH, stunResolver.getPreferredCandidate()); } /** @@ -127,7 +127,7 @@ public class STUNResolverTest extends SmackTestCase { iceResolver.addCandidate(cand3); iceResolver.addCandidate(cand4); - assertEquals(iceResolver.getPreferredCandidate(), candH); + assertEquals(candH, iceResolver.getPreferredCandidate()); } /** diff --git a/smack-jingle-old/src/integration-test/java/org/jivesoftware/smackx/jingle/nat/TransportCandidateTest.java b/smack-jingle-old/src/integration-test/java/org/jivesoftware/smackx/jingle/nat/TransportCandidateTest.java index 36830e911..763d52877 100644 --- a/smack-jingle-old/src/integration-test/java/org/jivesoftware/smackx/jingle/nat/TransportCandidateTest.java +++ b/smack-jingle-old/src/integration-test/java/org/jivesoftware/smackx/jingle/nat/TransportCandidateTest.java @@ -65,7 +65,7 @@ public class TransportCandidateTest extends SmackTestCase { candList.add(cand4); Collections.sort(candList); - assertEquals(candList.get(candList.size() - 1), candH); + assertEquals(candH, candList.get(candList.size() - 1)); } protected int getMaxConnections() { From 621dc4886561676f29c6fa44c2a52adcecbba2e4 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 10 Apr 2024 12:40:27 +0200 Subject: [PATCH 022/150] Smack 4.5.0-alpha3 --- version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version b/version index 0c77728e0..9f61a282f 100644 --- a/version +++ b/version @@ -1 +1 @@ -4.5.0-alpha3-SNAPSHOT +4.5.0-alpha3 From 78814d2f864dae4e5a6c7969742071e0f1397628 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 10 Apr 2024 13:20:52 +0200 Subject: [PATCH 023/150] Smack 4.5.0-alpha4-SNAPSHOT --- version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version b/version index 9f61a282f..196915bff 100644 --- a/version +++ b/version @@ -1 +1 @@ -4.5.0-alpha3 +4.5.0-alpha4-SNAPSHOT From 900b25235c10d67975a9b26cf16e1dd6e19ea8f4 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Wed, 10 Apr 2024 16:06:45 +0200 Subject: [PATCH 024/150] [sinttest] Refactoring XEP-0045 test for default roles When testing for default role assignment based on affiliation, depending on the 'adminGranted' callback is dangerous, as this callback appears to be only invoked when the affected occupant has already joined the room. The exact occupant count isn't something that these tests need to assert either. This commit changes the test implementations to proceed when all expected occupants have been detected by the user performing the change. These changes combined intend to make the tests more robust, with regards to the order in which several events are fired (which might be unexpeced, given threading implementation in server (clusters) and Smack stanza handling. --- ...AffiliationsPrivilegesIntegrationTest.java | 74 ++++++++++++------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java index f5fc7472f..53b44765c 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java @@ -25,7 +25,9 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; +import java.util.Set; import java.util.concurrent.TimeoutException; +import java.util.stream.Collectors; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; @@ -687,22 +689,30 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); final Resourcepart nicknameThree = Resourcepart.from("three-" + randomString); + final EntityFullJid jidOne = JidCreate.entityFullFrom(mucAddress, nicknameOne); + final EntityFullJid jidTwo = JidCreate.entityFullFrom(mucAddress, nicknameTwo); + final EntityFullJid jidThree = JidCreate.entityFullFrom(mucAddress, nicknameThree); + createMuc(mucAsSeenByOne, nicknameOne); + + final SimpleResultSyncPoint allOccupantsDetectedSyncPoint = new SimpleResultSyncPoint(); + final Set expectedOccupants = Set.of(jidOne, jidTwo, jidThree); + mucAsSeenByOne.addParticipantStatusListener(new ParticipantStatusListener() { + @Override + public void joined(EntityFullJid participant) { + if (mucAsSeenByOne.getOccupants().containsAll(expectedOccupants)) { + allOccupantsDetectedSyncPoint.signal(); + } + } + }); + try { + mucAsSeenByOne.grantAdmin(conTwo.getUser().asBareJid()); + mucAsSeenByTwo.join(nicknameTwo); mucAsSeenByThree.join(nicknameThree); - final SimpleResultSyncPoint resultSyncPoint = new SimpleResultSyncPoint(); - mucAsSeenByOne.addParticipantStatusListener(new ParticipantStatusListener() { - @Override - public void adminGranted(EntityFullJid participant) { - resultSyncPoint.signal(); - } - }); - mucAsSeenByOne.grantAdmin(conTwo.getUser().asBareJid()); - resultSyncPoint.waitForResult(timeout); - - assertEquals(3, mucAsSeenByOne.getOccupantsCount(), "Unexpected occupant count in room " + mucAddress); + assertResult(allOccupantsDetectedSyncPoint, "Expected " + conOne.getUser() + " to observe all of these occupants in room " + mucAddress + ", but not all of them appear to be in: " + expectedOccupants.stream().map(Object::toString).collect(Collectors.joining(", "))); assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant(JidCreate.entityFullFrom(mucAddress, nicknameOne)).getRole(), "Unexpected role for occupant " + nicknameOne + " of " + mucAddress); assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant(JidCreate.entityFullFrom(mucAddress, nicknameTwo)).getRole(), @@ -732,16 +742,23 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); final Resourcepart nicknameThree = Resourcepart.from("three-" + randomString); - final SimpleResultSyncPoint resultSyncPoint = new SimpleResultSyncPoint(); - mucAsSeenByOne.addParticipantStatusListener(new ParticipantStatusListener() { - @Override - public void adminGranted(EntityFullJid participant) { - resultSyncPoint.signal(); - } - }); + final EntityFullJid jidOne = JidCreate.entityFullFrom(mucAddress, nicknameOne); + final EntityFullJid jidTwo = JidCreate.entityFullFrom(mucAddress, nicknameTwo); + final EntityFullJid jidThree = JidCreate.entityFullFrom(mucAddress, nicknameThree); createModeratedMuc(mucAsSeenByOne, nicknameOne); + final SimpleResultSyncPoint allOccupantsDetectedSyncPoint = new SimpleResultSyncPoint(); + final Set expectedOccupants = Set.of(jidOne, jidTwo, jidThree); + mucAsSeenByOne.addParticipantStatusListener(new ParticipantStatusListener() { + @Override + public void joined(EntityFullJid participant) { + if (mucAsSeenByOne.getOccupants().containsAll(expectedOccupants)) { + allOccupantsDetectedSyncPoint.signal(); + } + } + }); + final MUCRole threeRole; switch (sinttestConfiguration.compatibilityMode) { default: @@ -753,12 +770,12 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs } try { + mucAsSeenByOne.grantAdmin(conTwo.getUser().asBareJid()); + mucAsSeenByTwo.join(nicknameTwo); mucAsSeenByThree.join(nicknameThree); - mucAsSeenByOne.grantAdmin(conTwo.getUser().asBareJid()); - resultSyncPoint.waitForResult(timeout); - assertEquals(3, mucAsSeenByOne.getOccupantsCount(), "Unexpected occupant count in room " + mucAddress); + assertResult(allOccupantsDetectedSyncPoint, "Expected " + conOne.getUser() + " to observe all of these occupants in room " + mucAddress + ", but not all of them appear to be in: " + expectedOccupants.stream().map(Object::toString).collect(Collectors.joining(", "))); assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant(JidCreate.entityFullFrom(mucAddress, nicknameOne)).getRole(), "Unexpected role for occupant " + nicknameOne + " of " + mucAddress); assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant(JidCreate.entityFullFrom(mucAddress, nicknameTwo)).getRole(), @@ -794,23 +811,26 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs createMembersOnlyMuc(mucAsSeenByOne, nicknameOne); - final SimpleResultSyncPoint adminResultSyncPoint = new SimpleResultSyncPoint(); + final SimpleResultSyncPoint allOccupantsDetectedSyncPoint = new SimpleResultSyncPoint(); + final Set expectedOccupants = Set.of(jidOne, jidTwo, jidThree); mucAsSeenByOne.addParticipantStatusListener(new ParticipantStatusListener() { @Override - public void adminGranted(EntityFullJid participant) { - adminResultSyncPoint.signal(); + public void joined(EntityFullJid participant) { + if (mucAsSeenByOne.getOccupants().containsAll(expectedOccupants)) { + allOccupantsDetectedSyncPoint.signal(); + } } }); try { mucAsSeenByOne.grantMembership(conTwo.getUser().asBareJid()); mucAsSeenByOne.grantMembership(conThree.getUser().asBareJid()); + mucAsSeenByOne.grantAdmin(conTwo.getUser().asBareJid()); mucAsSeenByTwo.join(nicknameTwo); mucAsSeenByThree.join(nicknameThree); - mucAsSeenByOne.grantAdmin(conTwo.getUser().asBareJid()); - adminResultSyncPoint.waitForResult(timeout); - assertEquals(3, mucAsSeenByOne.getOccupantsCount(), "Unexpected occupant count in room " + mucAddress); + + assertResult(allOccupantsDetectedSyncPoint, "Expected " + conOne.getUser() + " to observe all of these occupants in room " + mucAddress + ", but not all of them appear to be in: " + expectedOccupants.stream().map(Object::toString).collect(Collectors.joining(", "))); assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant(jidOne).getRole(), "Unexpected role for occupant " + jidOne + " in room " + mucAddress); assertEquals(MUCRole.moderator, mucAsSeenByOne.getOccupant(jidTwo).getRole(), "Unexpected role for occupant " + jidTwo + " in room " + mucAddress); assertEquals(MUCRole.participant, mucAsSeenByOne.getOccupant(jidThree).getRole(), "Unexpected role for occupant " + jidThree + " in room " + mucAddress); From d515a24e1cc63c51022c384f6b22a9ac600d0c46 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 11 Apr 2024 15:07:10 +0200 Subject: [PATCH 025/150] [sinttest] Fix processing of SpecificationReference When refactoring the original implementation, this annotation was expected to be present on methods. It later was changed to be a type-based annotation. This particular usage of the annotation was not properly modified to account for that change. --- .../smack/inttest/SmackIntegrationTestFramework.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java index ae8198ba7..a1008748a 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java @@ -138,7 +138,7 @@ public class SmackIntegrationTestFramework { for (FailedTest failedTest : testRunResult.failedIntegrationTests) { final Throwable cause = failedTest.failureReason; LOGGER.log(Level.SEVERE, failedTest.concreteTest + " failed: " + cause, cause); - if (failedTest.concreteTest.method.isAnnotationPresent(SpecificationReference.class)) { + if (failedTest.concreteTest.method.getDeclaringClass().isAnnotationPresent(SpecificationReference.class)) { final String specificationReference = getSpecificationReference(failedTest.concreteTest.method); if (specificationReference != null) { bySpecification.add("- " + specificationReference + " (as tested by '" + failedTest.concreteTest + "')"); From 5622bb07d1fd0403ec326b9feafc41af04e1adb8 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 11 Apr 2024 16:09:07 +0200 Subject: [PATCH 026/150] [sinttest] Allow custom processing of test run result This adds a new configuration option, `testRunResultProcessors`, that allows a user to customize the way the results of a test run is processed. By default, the pre-exising printing-to-stderr is used. --- .../smack/inttest/Configuration.java | 32 +++++++ .../SmackIntegrationTestFramework.java | 92 +++++++++++-------- .../smack/inttest/package-info.java | 17 ++++ 3 files changed, 103 insertions(+), 38 deletions(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java index 19c7d4d93..a60b3e21e 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.lang.reflect.Method; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -31,6 +32,7 @@ import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.logging.Logger; +import java.util.stream.Collectors; import javax.net.ssl.SSLContext; @@ -131,6 +133,8 @@ public final class Configuration { public final CompatibilityMode compatibilityMode; + public final List testRunResultProcessors; + private Configuration(Configuration.Builder builder) throws KeyManagementException, NoSuchAlgorithmException { service = Objects.requireNonNull(builder.service, "'service' must be set. Either via 'properties' files or via system property 'sinttest.service'."); @@ -203,6 +207,7 @@ public final class Configuration { this.dnsResolver = builder.dnsResolver; this.compatibilityMode = builder.compatibilityMode; + this.testRunResultProcessors = builder.testRunResultProcessors; } public boolean isAccountRegistrationPossible() { @@ -263,6 +268,8 @@ public final class Configuration { private CompatibilityMode compatibilityMode = CompatibilityMode.standardsCompliant; + private List testRunResultProcessors; + private Builder() { } @@ -473,6 +480,15 @@ public final class Configuration { return setCompatibilityMode(compatibilityMode); } + public Builder setTestRunResultProcessors(String testRunResultProcessorsString) { + if (testRunResultProcessorsString == null) { + return this; + } + + testRunResultProcessors = getTestRunProcessorListFrom(testRunResultProcessorsString); + return this; + } + public Configuration build() throws KeyManagementException, NoSuchAlgorithmException { return new Configuration(this); } @@ -550,6 +566,9 @@ public final class Configuration { builder.setCompatibilityMode(properties.getProperty("compatibilityMode")); + builder.setTestRunResultProcessors(properties.getProperty("testRunResultProcessors", + SmackIntegrationTestFramework.JulTestRunResultProcessor.class.getName())); + return builder.build(); } @@ -605,6 +624,19 @@ public final class Configuration { return split(input, Configuration::normalizeSpecification); } + private static List getTestRunProcessorListFrom(String input) { + return Arrays.stream(input.split(",")) + .map(element -> { + try { + final Class aClass = Class.forName(element).asSubclass(SmackIntegrationTestFramework.TestRunResultProcessor.class); + return aClass.getConstructor().newInstance(); + } catch (Exception e) { + throw new IllegalArgumentException("Unable to construct TestRunResultProcessor from value: " + element, e); + } + }) + .collect(Collectors.toList()); + } + private static Map> convertTestsToMap(Set tests) { Map> res = new HashMap<>(); for (String test : tests) { diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java index a1008748a..9cfb8a6b1 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java @@ -114,54 +114,65 @@ public class SmackIntegrationTestFramework { SmackIntegrationTestFramework sinttest = new SmackIntegrationTestFramework(config); TestRunResult testRunResult = sinttest.run(); - for (Map.Entry, Throwable> entry : testRunResult.impossibleTestClasses.entrySet()) { - LOGGER.info("Could not run " + entry.getKey().getName() + " because: " - + entry.getValue().getLocalizedMessage()); - } - for (TestNotPossible testNotPossible : testRunResult.impossibleIntegrationTests) { - LOGGER.info("Could not run " + testNotPossible.concreteTest + " because: " - + testNotPossible.testNotPossibleException.getMessage()); - } - for (SuccessfulTest successfulTest : testRunResult.successfulIntegrationTests) { - LOGGER.info(successfulTest.concreteTest + " ✔"); - } - final int successfulTests = testRunResult.successfulIntegrationTests.size(); - final int failedTests = testRunResult.failedIntegrationTests.size(); - final int availableTests = testRunResult.getNumberOfAvailableTests(); - LOGGER.info("SmackIntegrationTestFramework[" + testRunResult.testRunId + ']' + " finished: " - + successfulTests + '/' + availableTests + " [" + failedTests + " failed]"); - - final int exitStatus; - if (failedTests > 0) { - LOGGER.warning("💀 The following " + failedTests + " tests failed! 💀"); - final SortedSet bySpecification = new TreeSet<>(); - for (FailedTest failedTest : testRunResult.failedIntegrationTests) { - final Throwable cause = failedTest.failureReason; - LOGGER.log(Level.SEVERE, failedTest.concreteTest + " failed: " + cause, cause); - if (failedTest.concreteTest.method.getDeclaringClass().isAnnotationPresent(SpecificationReference.class)) { - final String specificationReference = getSpecificationReference(failedTest.concreteTest.method); - if (specificationReference != null) { - bySpecification.add("- " + specificationReference + " (as tested by '" + failedTest.concreteTest + "')"); - } - } + for (final TestRunResultProcessor testRunResultProcessor : config.testRunResultProcessors) { + try { + testRunResultProcessor.process(testRunResult); + } catch (Throwable t) { + LOGGER.log(Level.WARNING, "Invocation of TestRunResultProcessor " + testRunResultProcessor + " failed.", t); } - if (!bySpecification.isEmpty()) { - LOGGER.log(Level.SEVERE, "The failed tests correspond to the following specifications:" + System.lineSeparator() + String.join(System.lineSeparator(), bySpecification)); - } - - exitStatus = 2; - } else { - LOGGER.info("All possible Smack Integration Tests completed successfully. \\o/"); - exitStatus = 0; } if (config.debuggerFactory instanceof EnhancedDebugger) { EnhancedDebuggerWindow.getInstance().waitUntilClosed(); } + final int exitStatus = testRunResult.failedIntegrationTests.isEmpty() ? 0 : 2; System.exit(exitStatus); } + public static class JulTestRunResultProcessor implements TestRunResultProcessor { + + @Override + public void process(final TestRunResult testRunResult) { + for (Map.Entry, Throwable> entry : testRunResult.impossibleTestClasses.entrySet()) { + LOGGER.info("Could not run " + entry.getKey().getName() + " because: " + + entry.getValue().getLocalizedMessage()); + } + for (TestNotPossible testNotPossible : testRunResult.impossibleIntegrationTests) { + LOGGER.info("Could not run " + testNotPossible.concreteTest + " because: " + + testNotPossible.testNotPossibleException.getMessage()); + } + for (SuccessfulTest successfulTest : testRunResult.successfulIntegrationTests) { + LOGGER.info(successfulTest.concreteTest + " ✔"); + } + final int successfulTests = testRunResult.successfulIntegrationTests.size(); + final int failedTests = testRunResult.failedIntegrationTests.size(); + final int availableTests = testRunResult.getNumberOfAvailableTests(); + LOGGER.info("SmackIntegrationTestFramework[" + testRunResult.testRunId + ']' + " finished: " + + successfulTests + '/' + availableTests + " [" + failedTests + " failed]"); + + if (failedTests > 0) { + LOGGER.warning("💀 The following " + failedTests + " tests failed! 💀"); + final SortedSet bySpecification = new TreeSet<>(); + for (FailedTest failedTest : testRunResult.failedIntegrationTests) { + final Throwable cause = failedTest.failureReason; + LOGGER.log(Level.SEVERE, failedTest.concreteTest + " failed: " + cause, cause); + if (failedTest.concreteTest.method.getDeclaringClass().isAnnotationPresent(SpecificationReference.class)) { + final String specificationReference = getSpecificationReference(failedTest.concreteTest.method); + if (specificationReference != null) { + bySpecification.add("- " + specificationReference + " (as tested by '" + failedTest.concreteTest + "')"); + } + } + } + if (!bySpecification.isEmpty()) { + LOGGER.log(Level.SEVERE, "The failed tests correspond to the following specifications:" + System.lineSeparator() + String.join(System.lineSeparator(), bySpecification)); + } + } else { + LOGGER.info("All possible Smack Integration Tests completed successfully. \\o/"); + } + } + } + private static String getSpecificationReference(Method method) { final SpecificationReference spec = method.getDeclaringClass().getAnnotation(SpecificationReference.class); if (spec == null || spec.document().isBlank()) { @@ -665,6 +676,11 @@ public class SmackIntegrationTestFramework { return (Exception) e; } + @FunctionalInterface + public interface TestRunResultProcessor { + void process(SmackIntegrationTestFramework.TestRunResult testRunResult); + } + public static final class TestRunResult { /** diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java index 38898eced..c72d0afc2 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java @@ -167,6 +167,10 @@ * dnsResolver * One of ‘minidns’, ‘javax’ or ‘dnsjava’. Defaults to ‘minidns’. * + * + * testRunResultProcessors + * List of class names for generating test run output. Defaults to 'org.igniterealtime.smack.inttest.SmackIntegrationTestFramework$ConsoleTestRunResultProcessor' + * * *

Where to place the properties file

*

@@ -338,5 +342,18 @@ *

{@code
  * $ gradle integrationTest -Dsinttest.service=my.xmppservice.org -Dsinttest.testPackages=org.mypackage,org.otherpackage
  * }
+ *

Generating test run reports

+ *

+ * By default, the results of the test run is printed to standard-error. You can, however, provide your own processing + * for the test run results. To do so, create an implementation of + * {@link org.igniterealtime.smack.inttest.SmackIntegrationTestFramework.TestRunResultProcessor} and provide its class + * name to the testRunResultProcessor property. This property takes a comma separated list of class names. + *

+ *

+ * Example: + *

+ *
{@code
+ * $ gradle integrationTest -Dsinttest.service=my.xmppservice.org -Dsinttest.testRunResultProcessor=org.igniterealtime.smack.inttest.SmackIntegrationTestFramework$ConsoleTestRunResultProcessor
+ * }
*/ package org.igniterealtime.smack.inttest; From 77dc527a637279f224753957d63033e245f537fe Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Wed, 17 Apr 2024 10:05:17 +0200 Subject: [PATCH 027/150] [sinttest] Carry over assertion message when sync point times out `AbstractSmackIntTest#assertResult()` takes an argument that is an assertion message. When the sync point times out, that message should be logged. The following illustrates the change, as a result of this assertion failing: ``` assertResult(resultSyncPoint, "Expected " + conTwo.getUser() + " to receive message that was sent by " + conOne.getUser() + " in room " + mucAddress + " (but it did not)."); ``` Prior to this change, this is logged: ``` SEVERE: MultiUserChatIntegrationTest.mucTest (Normal) failed: java.util.concurrent.TimeoutException: Timeout expired java.util.concurrent.TimeoutException: Timeout expired at org.igniterealtime.smack.inttest.util.ResultSyncPoint.waitForResult(ResultSyncPoint.java:49) at org.igniterealtime.smack.inttest.AbstractSmackIntTest.assertResult(AbstractSmackIntTest.java:104) at org.igniterealtime.smack.inttest.AbstractSmackIntTest.assertResult(AbstractSmackIntTest.java:99) at org.jivesoftware.smackx.muc.MultiUserChatIntegrationTest.mucTest(MultiUserChatIntegrationTest.java:132) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) (snip) ``` With the change in this commit, that becomes: ``` SEVERE: MultiUserChatIntegrationTest.mucTest (Normal) failed: java.util.concurrent.TimeoutException: Expected smack-inttest-two-jskr4@example.org/two-jskr4 to receive message that was sent by smack-inttest-one-jskr4@example.org/one-jskr4 in room smack-inttest-message-jskr4-aud43i@conference.example.org (but it did not). java.util.concurrent.TimeoutException: Expected smack-inttest-two-jskr4@example.org/two-jskr4 to receive message that was sent by smack-inttest-one-jskr4@example.org/one-jskr4 in room smack-inttest-message-jskr4-aud43i@conference.example.org (but it did not). at org.igniterealtime.smack.inttest.util.ResultSyncPoint.waitForResult(ResultSyncPoint.java:53) at org.igniterealtime.smack.inttest.AbstractSmackIntTest.assertResult(AbstractSmackIntTest.java:104) at org.igniterealtime.smack.inttest.AbstractSmackIntTest.assertResult(AbstractSmackIntTest.java:99) at org.jivesoftware.smackx.muc.MultiUserChatIntegrationTest.mucTest(MultiUserChatIntegrationTest.java:132) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) (snip) ``` --- .../igniterealtime/smack/inttest/AbstractSmackIntTest.java | 2 +- .../igniterealtime/smack/inttest/util/ResultSyncPoint.java | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/AbstractSmackIntTest.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/AbstractSmackIntTest.java index c372103dc..11334dee8 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/AbstractSmackIntTest.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/AbstractSmackIntTest.java @@ -101,7 +101,7 @@ public abstract class AbstractSmackIntTest { public static R assertResult(ResultSyncPoint syncPoint, long timeout, String message) throws InterruptedException, TimeoutException, AssertionFailedError { try { - return syncPoint.waitForResult(timeout); + return syncPoint.waitForResult(timeout, message); } catch (InterruptedException | TimeoutException e) { throw e; } catch (Exception e) { diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/ResultSyncPoint.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/ResultSyncPoint.java index 37b143934..f7f10b63f 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/ResultSyncPoint.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/ResultSyncPoint.java @@ -26,6 +26,10 @@ public class ResultSyncPoint { private E exception; public R waitForResult(long timeout) throws E, InterruptedException, TimeoutException { + return waitForResult(timeout, null); + } + + public R waitForResult(long timeout, String timeoutMessage) throws E, InterruptedException, TimeoutException { synchronized (this) { if (result != null) { return result; @@ -46,7 +50,7 @@ public class ResultSyncPoint { if (exception != null) { throw exception; } - throw new TimeoutException("Timeout expired"); + throw new TimeoutException(timeoutMessage == null ? "Timeout expired" : timeoutMessage); } From 26ec0d412d335d2c127f2928bc4f57a266cdc4c5 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Wed, 23 Feb 2022 14:29:25 +0100 Subject: [PATCH 028/150] SINT: Add roster tests that are driven by presence stanzas RFC-6121 defines server-sided behavior of the interaction between presence stanzas and rosters. This commit adds tests for that behavior. --- .../smack/roster/RosterIntegrationTest.java | 442 +++++++++++++++++- 1 file changed, 438 insertions(+), 4 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java index 5f951c1d5..23cb49deb 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java @@ -1,6 +1,6 @@ /** * - * Copyright 2015-2020 Florian Schmaus + * Copyright 2015-2020 Florian Schmaus, 2022-2024 Guus der Kinderen * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,21 +16,40 @@ */ package org.jivesoftware.smack.roster; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + import java.util.Collection; import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; +import org.jivesoftware.smack.StanzaListener; +import org.jivesoftware.smack.filter.AndFilter; +import org.jivesoftware.smack.filter.FromMatchesFilter; +import org.jivesoftware.smack.filter.PresenceTypeFilter; +import org.jivesoftware.smack.filter.StanzaTypeFilter; +import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler; +import org.jivesoftware.smack.iqrequest.IQRequestHandler; +import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Presence; +import org.jivesoftware.smack.packet.PresenceBuilder; +import org.jivesoftware.smack.roster.packet.RosterPacket; import org.jivesoftware.smack.roster.packet.RosterPacket.ItemType; +import org.jivesoftware.smack.sm.predicates.ForEveryStanza; +import org.jivesoftware.smack.util.Consumer; import org.jivesoftware.smack.util.StringUtils; import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.IntegrationTestRosterUtil; +import org.igniterealtime.smack.inttest.util.ResultSyncPoint; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; import org.jxmpp.jid.BareJid; import org.jxmpp.jid.Jid; +@SpecificationReference(document = "RFC6121") public class RosterIntegrationTest extends AbstractSmackIntegrationTest { private final Roster rosterOne; @@ -59,7 +78,7 @@ public class RosterIntegrationTest extends AbstractSmackIntegrationTest { final String conTwosRosterName = "ConTwo " + testRunId; final SimpleResultSyncPoint addedAndSubscribed = new SimpleResultSyncPoint(); - rosterOne.addRosterListener(new AbstractRosterListener() { + final RosterListener rosterListener = new AbstractRosterListener() { @Override public void entriesAdded(Collection addresses) { checkIfAddedAndSubscribed(addresses); @@ -94,17 +113,432 @@ public class RosterIntegrationTest extends AbstractSmackIntegrationTest { addedAndSubscribed.signal(); } } - }); + }; + + rosterOne.addRosterListener(rosterListener); try { rosterOne.createItemAndRequestSubscription(conTwo.getUser().asBareJid(), conTwosRosterName, null); - assertResult(addedAndSubscribed, 2 * connection.getReplyTimeout(), + assertResult(addedAndSubscribed, "A roster entry for " + conTwo.getUser().asBareJid() + " using the name '" + conTwosRosterName + "' of type 'to' was expected to be added to the roster of " + conOne.getUser() + " (but it was not)."); } finally { rosterTwo.removeSubscribeListener(subscribeListener); + rosterOne.removeRosterListener(rosterListener); } } + /** + * Asserts that when a user sends out a presence subscription request, the server sends a roster push back to the + * user. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "3.1.2", quote = + "After locally delivering or remotely routing the presence subscription request, the user's server MUST then " + + "send a roster push to all of the user's interested resources, containing the potential contact with a " + + "subscription state of \"none\" and with notation that the subscription is pending (via an 'ask' attribute " + + "whose value is \"subscribe\").") + public void testRosterPushAfterSubscriptionRequest() throws Exception { + IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); + Roster.getInstanceFor(conTwo).setSubscriptionMode(Roster.SubscriptionMode.manual); // prevents a race condition when asserting the captured roster entry. + final ResultSyncPoint added = new ResultSyncPoint<>(); + + final RosterListener rosterListener = new AbstractRosterListener() { + @Override + public void entriesAdded(Collection addresses) { + for (Jid jid : addresses) { + if (!jid.equals(conTwo.getUser().asBareJid())) { + continue; + } + final BareJid bareJid = conTwo.getUser().asBareJid(); + RosterEntry rosterEntry = rosterOne.getEntry(bareJid); + added.signal(rosterEntry); + return; + } + } + }; + rosterOne.addRosterListener(rosterListener); + + final Presence subscribe = conOne.getStanzaFactory().buildPresenceStanza() + .ofType(Presence.Type.subscribe) + .to(conTwo.getUser().asBareJid()) + .build(); + + try { + conOne.sendStanza(subscribe); + + final RosterEntry rosterEntry = assertResult(added, "Expected the server to send a roster push back to '" + conOne.getUser() + "' after they sent a presence subscription request to '" + conTwo.getUser().asBareJid() + "' (but the server did not)."); + assertEquals(ItemType.none, rosterEntry.getType(), "Unexpected subscription type on roster push after '" + conOne.getUser() + "' sent a presence subscription request to '" + conTwo.getUser().asBareJid() + "'."); + assertTrue(rosterEntry.isSubscriptionPending(), "Missing 'ask=subscribe' attribute on roster push after '" + conOne.getUser() + "' sent a presence subscription request to '" + conTwo.getUser().asBareJid() + "'."); + } finally { + rosterTwo.setSubscriptionMode(Roster.getDefaultSubscriptionMode()); + rosterOne.removeRosterListener(rosterListener); + } + } + + /** + * Asserts that when a user sends out a presence subscription request to an entity for which the user already has + * an approved subscription, the server sends an auto-reply back to the user. + * + *

From RFC6121 § 3.1.3:

+ *
+ * If the contact exists and the user already has a subscription to the contact's presence, then the contact's + * server MUST auto-reply on behalf of the contact by sending a presence stanza of type "subscribed" from the + * contact's bare JID to the user's bare JID. + *
+ * + * @throws Exception when errors occur + */ + @SmackIntegrationTest + public void testAutoReplyForRequestWhenAlreadySubscribed() throws Exception { + IntegrationTestRosterUtil.ensureBothAccountsAreSubscribedToEachOther(conOne, conTwo, connection.getReplyTimeout()); + + final SimpleResultSyncPoint added = new SimpleResultSyncPoint(); + + final StanzaListener stanzaListener = stanza -> { + final Presence presence = (Presence) stanza; + if (!presence.getTo().isEntityBareJid()) { + added.signalFailure("'to' address should be a bare JID, but is a full JID."); + } else if (!presence.getFrom().isEntityBareJid()) { + added.signalFailure("'from' address should be a bare JID, but is a full JID."); + } else if (presence.getType() != Presence.Type.subscribed) { + added.signalFailure("Incorrect subscription type on auto-reply: " + presence.getType()); + } else { + added.signal(); + } + }; + + conOne.addAsyncStanzaListener(stanzaListener, new AndFilter(StanzaTypeFilter.PRESENCE, FromMatchesFilter.createBare(conTwo.getUser()))); + + final Presence subscribe = PresenceBuilder.buildPresence() + .ofType(Presence.Type.subscribe) + .to(conTwo.getUser().asBareJid()) + .build(); + + try { + conOne.sendStanza(subscribe); + + assertTrue(added.waitForResult(2 * connection.getReplyTimeout())); + } finally { + conOne.removeAsyncStanzaListener(stanzaListener); + } + } + + /** + * Asserts that when a user sends out a presence subscription request to an entity for which the user does not have + * a pre-existing subscription, the server will deliver the subscription request to that entity. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "3.1.3", quote = + "if there is at least one available resource associated with the contact when the subscription request is " + + "received by the contact's server, then the contact's server MUST send that subscription request to all " + + "available resources in accordance with Section 8.") + public void testPresenceDeliveredToRecipient() throws Exception { + IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); + + final ResultSyncPoint added = new ResultSyncPoint<>(); + final StanzaListener stanzaListener = stanza -> added.signal((Presence) stanza); + conTwo.addAsyncStanzaListener(stanzaListener, new AndFilter(StanzaTypeFilter.PRESENCE, FromMatchesFilter.createBare(conOne.getUser()))); + + final Presence subscribe = conOne.getStanzaFactory().buildPresenceStanza() + .ofType(Presence.Type.subscribe) + .to(conTwo.getUser().asBareJid()) + .build(); + + try { + conOne.sendStanza(subscribe); + final Presence received = assertResult(added, "Expected subscription request from '" + conOne.getUser() + "' to '" + conTwo.getUser().asBareJid() + "' to be delivered to " + conTwo.getUser() + " (but it did not)."); + assertEquals(Presence.Type.subscribe, received.getType(), "Unexpected presence type in presence stanza received by '" + conTwo.getUser() + "' after '" + conOne.getUser() + "' sent a presence subscription request."); + } finally { + conTwo.removeAsyncStanzaListener(stanzaListener); + } + } + + /** + * Asserts that when a user sends a presence subscription approval, the server stamps the bare JID of the sender, + * and delivers it to the requester. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "3.1.5", quote = + "When the contact's client sends the subscription approval, the contact's server MUST stamp the outbound " + + "stanza with the bare JID of the contact and locally deliver or remotely route the " + + "stanza to the user.") + public void testPresenceApprovalStampedAndDelivered() throws Exception { + IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); + + rosterTwo.setSubscriptionMode(Roster.SubscriptionMode.accept_all); + + // Modify the outbound 'subscribed' stanza, to be 'wrong' (addressed to a full rather than a bare JID), to test if the server overrides this. + final Consumer interceptor = (PresenceBuilder presenceBuilder) -> presenceBuilder.to(conOne.getUser()).build(); + conTwo.addPresenceInterceptor(interceptor, p -> p.getType() == Presence.Type.subscribed); + + final ResultSyncPoint added = new ResultSyncPoint<>(); + final StanzaListener stanzaListener = stanza -> added.signal((Presence) stanza); + + conOne.addAsyncStanzaListener(stanzaListener, PresenceTypeFilter.SUBSCRIBED); + + final Presence subscribe = conOne.getStanzaFactory().buildPresenceStanza() + .ofType(Presence.Type.subscribe) + .to(conTwo.getUser().asBareJid()) + .build(); + + try { + conOne.sendStanza(subscribe); + + final Presence received = assertResult(added, "Expected presence 'subscribed' stanza to be delivered to '" + conOne.getUser() + "' after '" + conTwo.getUser() + "' approved their subscription request (but it was not)."); + assertEquals(conTwo.getUser().asBareJid(), received.getFrom().asEntityBareJidOrThrow(), "Expected presence 'subscribed' stanza that was delivered to '" + conOne.getUser() + "' after '" + conTwo.getUser() + "' approved their subscription request to have a 'from' attribute value that is associated to '" + conTwo.getUser().getLocalpart() + "' (but it did not)."); + assertTrue(received.getFrom().isEntityBareJid(), "Expected presence 'subscribed' stanza that was delivered to '" + conOne.getUser() + "' after '" + conTwo.getUser() + "' approved their subscription request to have a 'from' attribute value that is a bare JID (but it was not)."); + } finally { + rosterTwo.setSubscriptionMode(Roster.getDefaultSubscriptionMode()); + conTwo.removePresenceInterceptor(interceptor); + conOne.removeAsyncStanzaListener(stanzaListener); + } + } + + /** + * Asserts that when a user sends a presence subscription approval, the server sends a roster push to the user with + * a subscription 'from'. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "3.1.5", quote = + "The contact's server then MUST send an updated roster push to all of the contact's interested resources, " + + "with the 'subscription' attribute set to a value of \"from\".") + public void testPresenceApprovalYieldsRosterPush() throws Exception { + IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); + + rosterTwo.setSubscriptionMode(Roster.SubscriptionMode.accept_all); + + final ResultSyncPoint updated = new ResultSyncPoint<>(); + + final RosterListener rosterListener = new AbstractRosterListener() { + @Override + public void entriesAdded(Collection addresses) { + for (Jid jid : addresses) { + if (!jid.equals(conOne.getUser().asBareJid())) { + continue; + } + BareJid bareJid = conOne.getUser().asBareJid(); + RosterEntry rosterEntry = rosterTwo.getEntry(bareJid); + updated.signal(rosterEntry); + } + } + }; + rosterTwo.addRosterListener(rosterListener); + + final Presence subscribe = conOne.getStanzaFactory().buildPresenceStanza() + .ofType(Presence.Type.subscribe) + .to(conTwo.getUser().asBareJid()) + .build(); + + try { + conOne.sendStanza(subscribe); + // The 'subscribe' gets automatically approved by conTwo. + + final RosterEntry entry = assertResult(updated, "Expected '" + conTwo.getUser() + "' to receive a roster push with an update for the entry of '" + conOne.getUser().asBareJid() + "' after '" + conTwo.getUser() + "' approved their subscription request."); + assertEquals(ItemType.from, entry.getType(), "Unexpected type for '" + conOne.getUser().asBareJid() + "''s entry in '" + conTwo.getUser().asBareJid() + "''s roster."); + } finally { + rosterTwo.setSubscriptionMode(Roster.getDefaultSubscriptionMode()); + rosterTwo.removeRosterListener(rosterListener); + } + } + + /** + * Asserts that when a user sends a presence subscription approval, the server sends a roster push to the user with + * a subscription 'both' when the contact already has a subscription to the other entity. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "3.1.5", quote = + "The contact's server then MUST send an updated roster push to all of the contact's interested resources, " + + "with the 'subscription' attribute set to a value of \"from\". (Here we assume that the contact does not " + + "already have a subscription to the user; if that were the case, the 'subscription' attribute would be set " + + "to a value of \"both\", as explained under Appendix A.)") + public void testPresenceApprovalYieldsRosterPush2() throws Exception { + IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); + + // Setup fixture: establish one-way subscription. + rosterOne.setSubscriptionMode(Roster.SubscriptionMode.accept_all); + + final SimpleResultSyncPoint fixtureComplete = new SimpleResultSyncPoint(); + RosterListener rosterListenerTwo = new AbstractRosterListener() { + @Override + public void entriesAdded(Collection addresses) { + checkIfAdded(addresses); + } + @Override + public void entriesUpdated(Collection addresses) { + checkIfAdded(addresses); + } + private void checkIfAdded(Collection addresses) { + for (Jid jid : addresses) { + final BareJid bareJid = conOne.getUser().asBareJid(); + if (!jid.equals(bareJid)) { + continue; + } + if (rosterTwo.getEntry(bareJid) == null) { + continue; + } + if (rosterTwo.getEntry(bareJid).getType() == ItemType.none) { + continue; + } + fixtureComplete.signal(); + rosterTwo.removeRosterListener(this); + } + } + }; + rosterTwo.addRosterListener(rosterListenerTwo); + + final Presence subscribeOne = conTwo.getStanzaFactory().buildPresenceStanza() + .ofType(Presence.Type.subscribe) + .to(conOne.getUser().asBareJid()) + .build(); + try { + conTwo.sendStanza(subscribeOne); + + fixtureComplete.waitForResult(connection.getReplyTimeout()); + } finally { + rosterOne.setSubscriptionMode(Roster.getDefaultSubscriptionMode()); + rosterTwo.removeRosterListener(rosterListenerTwo); + } + + // Setup fixture is now complete. Execute the test. + rosterTwo.setSubscriptionMode(Roster.SubscriptionMode.accept_all); + + final ResultSyncPoint updated = new ResultSyncPoint<>(); + + rosterListenerTwo = new AbstractRosterListener() { + @Override + public void entriesUpdated(Collection addresses) { + for (Jid jid : addresses) { + if (!jid.equals(conOne.getUser().asBareJid())) { + continue; + } + BareJid bareJid = conOne.getUser().asBareJid(); + updated.signal(rosterTwo.getEntry(bareJid)); + } + } + }; + rosterTwo.addRosterListener(rosterListenerTwo); + + final Presence subscribeTwo = conOne.getStanzaFactory().buildPresenceStanza() + .ofType(Presence.Type.subscribe) + .to(conTwo.getUser().asBareJid()) + .build(); + + try { + conOne.sendStanza(subscribeTwo); + + final RosterEntry entry = assertResult(updated, "Expected '" + conTwo.getUser() + "' to receive a roster push with an update for the entry of '" + conOne.getUser().asBareJid() + "' after '" + conOne.getUser() + "' approved their subscription request."); + assertEquals(ItemType.both, entry.getType(), "Unexpected type for '" + conOne.getUser().asBareJid() + "''s entry in '" + conTwo.getUser().asBareJid() + "''s roster."); + } finally { + rosterTwo.setSubscriptionMode(Roster.getDefaultSubscriptionMode()); + rosterTwo.removeRosterListener(rosterListenerTwo); + } + } + + /** + * Asserts that when a presence subscription request is approved, the server sends the latest presence of the now + * subscribed entity to the subscriber. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "3.1.5", quote = + "The contact's server MUST then also send current presence to the user from each of the contact's available resources.") + public void testCurrentPresenceSentAfterSubscriptionApproval() throws Exception { + IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); + + final String needle = "Look for me!"; + conTwo.sendStanza(conTwo.getStanzaFactory().buildPresenceStanza().setStatus(needle).build()); + + rosterTwo.setSubscriptionMode(Roster.SubscriptionMode.accept_all); + + final SimpleResultSyncPoint received = new SimpleResultSyncPoint(); + final StanzaListener stanzaListener = stanza -> { + final Presence presence = (Presence) stanza; + if (presence.getStatus().equals(needle)) { + received.signal(); + } + }; + conOne.addAsyncStanzaListener(stanzaListener, new AndFilter(StanzaTypeFilter.PRESENCE, FromMatchesFilter.createBare(conTwo.getUser()))); + + final Presence subscribe = conOne.getStanzaFactory().buildPresenceStanza() + .ofType(Presence.Type.subscribe) + .to(conTwo.getUser().asBareJid()) + .build(); + + try { + conOne.sendStanza(subscribe); + + assertResult(received, "Expected '" + conTwo.getUser() + "' to receive '" + conOne.getUser() + "''s current presence update (including the status '" + needle + "'), but it did not."); + } finally { + rosterTwo.setSubscriptionMode(Roster.getDefaultSubscriptionMode()); + conOne.removeAsyncStanzaListener(stanzaListener); + } + } + + /** + * Asserts that when a user receives a presence subscription approval, the server first sends the presence stanza, + * followed by a roster push. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "3.1.6", quote = + "(...) If this check is successful, then the user's server MUST: 1. Deliver the inbound subscription " + + "approval to all of the user's interested resources (...). This MUST occur before sending the roster push " + + "described in the next step. 2. Initiate a roster push to all of the user's interested resources, containing " + + "an updated roster item for the contact with the 'subscription' attribute set to a value of \"to\" (...) or " + + "\"both\" (...).") + public void testReceivePresenceApprovalAndRosterPush() throws Exception { + IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); + + rosterTwo.setSubscriptionMode(Roster.SubscriptionMode.accept_all); + + final ResultSyncPoint receivedRosterPush = new ResultSyncPoint<>(); + final AtomicBoolean hasReceivedSubscriptionApproval = new AtomicBoolean(false); + + // Replace the IQ Request Handler that processes roster pushes with one that's guaranteed to be executed + // synchronously with the stanza handler that listens for presence updates (below). This is to guarantee that + // the order in which both stanzas arrive is maintained during processing. + final IQRequestHandler synchronousReplacement = new AbstractIqRequestHandler(RosterPacket.ELEMENT, RosterPacket.NAMESPACE, IQ.Type.set, IQRequestHandler.Mode.sync) { + @Override + public IQ handleIQRequest(IQ iqRequest) { + receivedRosterPush.signal(hasReceivedSubscriptionApproval.get()); + return IQ.createResultIQ(iqRequest); + } + }; + final IQRequestHandler originalRequestHandler = conOne.registerIQRequestHandler(synchronousReplacement); + + final StanzaListener presenceUpdateListener = stanza -> { + if (stanza instanceof Presence) { + final Presence presence = (Presence) stanza; + if (presence.getType() == Presence.Type.subscribed) { + hasReceivedSubscriptionApproval.set(true); + } + } + }; + + // Add as a synchronous listener, again to guarantee to maintain the order of the stanzas captured by this + // listener and the roster pushes captured by the IQ Request Handler (above). + conOne.addSyncStanzaListener(presenceUpdateListener, ForEveryStanza.INSTANCE); + + final Presence subscribe = conOne.getStanzaFactory().buildPresenceStanza() + .ofType(Presence.Type.subscribe) + .to(conTwo.getUser().asBareJid()) + .build(); + + try { + conOne.sendStanza(subscribe); + final boolean hasReceivedApproval = assertResult(receivedRosterPush, "Expected '" + conOne.getUser() + "' to receive a roster push containing an updated roster entry for '" + conTwo.getUser().asBareJid() + "'"); + assertTrue(hasReceivedApproval, "Expected '" + conOne.getUser() + "' to have received a presence subscription approval from '" + conTwo.getUser().asBareJid() + "', before it received the roster push that contained the updated contact, but the presence subscription approval was not (yet) received when the roster push was."); + } finally { + rosterOne.setSubscriptionMode(Roster.getDefaultSubscriptionMode()); + conOne.removeSyncStanzaListener(presenceUpdateListener); + conOne.registerIQRequestHandler(originalRequestHandler); + } + } } From ad756810c1b2e49990534d30af9b3cb8e11de60b Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 3 Mar 2022 17:06:25 +0100 Subject: [PATCH 029/150] SINT: Removing invalid test The implementation of the test that is being removed depends on a server characteristic that will cause a loop of presence stanzas (which obviously is bad). A RFC3921-compliant client can send an 'acknowledgement' after receiving a presence 'subscribed' stanza, in the form of a presence 'subscribe' stanza. See section 8.2 of RFC3921. When a server implementation does not ignore this acknowledgement, the domain of the recipient MUST (RFC6121 section 3.1.3) respond with a 'subscribed' on behalf of the recipient (which is what the now removed test was verifying). This can trigger the RFC3921-compliant sender to again receive 'subscribed', that it again can acknowledge, which causes a loop. To test RFC6121, the subscription state of the recipient must somehow be modified to reflect a different state than that of the initiator. I'm not sure if that is feasible with the SINT framework. --- .../smack/roster/RosterIntegrationTest.java | 48 ------------------- 1 file changed, 48 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java index 23cb49deb..091293c4d 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java @@ -178,54 +178,6 @@ public class RosterIntegrationTest extends AbstractSmackIntegrationTest { } } - /** - * Asserts that when a user sends out a presence subscription request to an entity for which the user already has - * an approved subscription, the server sends an auto-reply back to the user. - * - *

From RFC6121 § 3.1.3:

- *
- * If the contact exists and the user already has a subscription to the contact's presence, then the contact's - * server MUST auto-reply on behalf of the contact by sending a presence stanza of type "subscribed" from the - * contact's bare JID to the user's bare JID. - *
- * - * @throws Exception when errors occur - */ - @SmackIntegrationTest - public void testAutoReplyForRequestWhenAlreadySubscribed() throws Exception { - IntegrationTestRosterUtil.ensureBothAccountsAreSubscribedToEachOther(conOne, conTwo, connection.getReplyTimeout()); - - final SimpleResultSyncPoint added = new SimpleResultSyncPoint(); - - final StanzaListener stanzaListener = stanza -> { - final Presence presence = (Presence) stanza; - if (!presence.getTo().isEntityBareJid()) { - added.signalFailure("'to' address should be a bare JID, but is a full JID."); - } else if (!presence.getFrom().isEntityBareJid()) { - added.signalFailure("'from' address should be a bare JID, but is a full JID."); - } else if (presence.getType() != Presence.Type.subscribed) { - added.signalFailure("Incorrect subscription type on auto-reply: " + presence.getType()); - } else { - added.signal(); - } - }; - - conOne.addAsyncStanzaListener(stanzaListener, new AndFilter(StanzaTypeFilter.PRESENCE, FromMatchesFilter.createBare(conTwo.getUser()))); - - final Presence subscribe = PresenceBuilder.buildPresence() - .ofType(Presence.Type.subscribe) - .to(conTwo.getUser().asBareJid()) - .build(); - - try { - conOne.sendStanza(subscribe); - - assertTrue(added.waitForResult(2 * connection.getReplyTimeout())); - } finally { - conOne.removeAsyncStanzaListener(stanzaListener); - } - } - /** * Asserts that when a user sends out a presence subscription request to an entity for which the user does not have * a pre-existing subscription, the server will deliver the subscription request to that entity. From 8efa4bd7323d7b77d56e9eaed9d25e96afe701e6 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Fri, 26 Apr 2024 17:16:03 +0200 Subject: [PATCH 030/150] [sinttest] Expand list of default test packages The default set of packages that is scanned for integration tests are referencing jivesoftware. This commit adds igniterealtime-oriented package names. --- .../smack/inttest/SmackIntegrationTestFramework.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java index a1008748a..eec07893b 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java @@ -223,7 +223,7 @@ public class SmackIntegrationTestFramework { String[] testPackages; if (config.testPackages == null || config.testPackages.isEmpty()) { - testPackages = new String[] { "org.jivesoftware.smackx", "org.jivesoftware.smack" }; + testPackages = new String[] { "org.jivesoftware.smackx", "org.jivesoftware.smack", "org.igniterealtime.smackx", "org.igniterealtime.smack" }; } else { testPackages = config.testPackages.toArray(new String[config.testPackages.size()]); From 855f01e6b2d8e35ee6ac440f204e9d91e80c645c Mon Sep 17 00:00:00 2001 From: Dan Caseley Date: Thu, 17 Jun 2021 18:40:45 +0100 Subject: [PATCH 031/150] [sinttest] Additional tests for s7 of XEP-0045 --- .../smackx/muc/MucConfigFormManager.java | 13 +- .../inttest/util/MultiResultSyncPoint.java | 59 + .../AbstractMultiUserChatIntegrationTest.java | 73 ++ .../MultiUserChatEntityIntegrationTest.java | 30 +- .../muc/MultiUserChatIntegrationTest.java | 67 +- .../MultiUserChatOccupantIntegrationTest.java | 1102 +++++++++++++++++ .../util/MultiResultSyncPointTest.java | 108 ++ .../inttest/util/ResultSyncPointTest.java | 13 + 8 files changed, 1393 insertions(+), 72 deletions(-) create mode 100644 smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/MultiResultSyncPoint.java create mode 100644 smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java create mode 100644 smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/util/MultiResultSyncPointTest.java diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java index 1735d0b4f..80371f7c8 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java @@ -223,6 +223,15 @@ public class MucConfigFormManager { } + /** + * Check if the room supports its visibility being controlled vioa configuration. + * + * @return true if supported, false if not. + */ + public boolean supportsPublicRoom() { + return answerForm.hasField(MUC_ROOMCONFIG_PUBLICLYSEARCHABLEROOM); + } + /** * Make the room publicly searchable. * @@ -251,7 +260,7 @@ public class MucConfigFormManager { * @throws MucConfigurationNotSupportedException if the requested MUC configuration is not supported by the MUC service. */ public MucConfigFormManager setPublic(boolean isPublic) throws MucConfigurationNotSupportedException { - if (!supportsModeration()) { + if (!supportsPublicRoom()) { throw new MucConfigurationNotSupportedException(MUC_ROOMCONFIG_PUBLICLYSEARCHABLEROOM); } answerForm.setAnswer(MUC_ROOMCONFIG_PUBLICLYSEARCHABLEROOM, isPublic); @@ -299,7 +308,7 @@ public class MucConfigFormManager { */ public MucConfigFormManager setIsPasswordProtected(boolean isPasswordProtected) throws MucConfigurationNotSupportedException { - if (!supportsMembersOnly()) { + if (!supportsPasswordProtected()) { throw new MucConfigurationNotSupportedException(MUC_ROOMCONFIG_PASSWORDPROTECTEDROOM); } answerForm.setAnswer(MUC_ROOMCONFIG_PASSWORDPROTECTEDROOM, isPasswordProtected); diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/MultiResultSyncPoint.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/MultiResultSyncPoint.java new file mode 100644 index 000000000..22e046d64 --- /dev/null +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/MultiResultSyncPoint.java @@ -0,0 +1,59 @@ +/** + * + * Copyright 2021 Guus der Kinderen + * + * 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.igniterealtime.smack.inttest.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeoutException; + +import org.jivesoftware.smack.util.Objects; + +public class MultiResultSyncPoint { + + private final List results; + private E exception; + private final int expectedResultCount; + + public MultiResultSyncPoint(int expectedResultCount) { + this.expectedResultCount = expectedResultCount; + this.results = new ArrayList<>(expectedResultCount); + } + + public synchronized List waitForResults(long timeout) throws E, InterruptedException, TimeoutException { + long now = System.currentTimeMillis(); + final long deadline = now + timeout; + while (results.size() < expectedResultCount && exception == null && now < deadline) { + wait(deadline - now); + now = System.currentTimeMillis(); + } + if (now >= deadline) throw new TimeoutException("Timeout waiting " + timeout + " millis"); + if (exception != null) throw exception; + return new ArrayList<>(results); + } + + public synchronized void signal(R result) { + this.results.add(Objects.requireNonNull(result)); + if (expectedResultCount <= results.size()) { + notifyAll(); + } + } + + public synchronized void signal(E exception) { + this.exception = Objects.requireNonNull(exception); + notifyAll(); + } +} diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/AbstractMultiUserChatIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/AbstractMultiUserChatIntegrationTest.java index 22316ed6e..2ad9ca2d4 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/AbstractMultiUserChatIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/AbstractMultiUserChatIntegrationTest.java @@ -22,6 +22,8 @@ import java.util.List; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.util.StringUtils; +import org.jivesoftware.smackx.xdata.form.FillableForm; +import org.jivesoftware.smackx.xdata.form.Form; import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; @@ -140,4 +142,75 @@ public abstract class AbstractMultiUserChatIntegrationTest extends AbstractSmack .makeHidden() .submitConfigurationForm(); } + + /** + * Creates a non-anonymous room. + * + *

From XEP-0045 § 10.1.3:

+ *
+ * Note: The _whois configuration option specifies whether the room is non-anonymous (a value of "anyone"), + * semi-anonymous (a value of "moderators"), or fully anonmyous (a value of "none", not shown here). + *
+ */ + static void createNonAnonymousMuc(MultiUserChat muc, Resourcepart resourceName) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, InterruptedException, MultiUserChatException.MucAlreadyJoinedException, SmackException.NotConnectedException, MultiUserChatException.MissingMucCreationAcknowledgeException, MultiUserChatException.NotAMucServiceException { + muc.create(resourceName); + Form configForm = muc.getConfigurationForm(); + FillableForm answerForm = configForm.getFillableForm(); + answerForm.setAnswer("muc#roomconfig_whois", "anyone"); + muc.sendConfigurationForm(answerForm); + } + + /** + * Creates a semi-anonymous room. + * + *

From XEP-0045 § 10.1.3:

+ *
+ * Note: The _whois configuration option specifies whether the room is non-anonymous (a value of "anyone"), + * semi-anonymous (a value of "moderators"), or fully anonmyous (a value of "none", not shown here). + *
+ */ + static void createSemiAnonymousMuc(MultiUserChat muc, Resourcepart resourceName) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, InterruptedException, MultiUserChatException.MucAlreadyJoinedException, SmackException.NotConnectedException, MultiUserChatException.MissingMucCreationAcknowledgeException, MultiUserChatException.NotAMucServiceException { + muc.create(resourceName); + Form configForm = muc.getConfigurationForm(); + FillableForm answerForm = configForm.getFillableForm(); + answerForm.setAnswer("muc#roomconfig_whois", "moderators"); + muc.sendConfigurationForm(answerForm); + } + + /** + * Creates a password-protected room. + */ + static void createPasswordProtectedMuc(MultiUserChat muc, Resourcepart resourceName, String password) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, InterruptedException, MultiUserChatException.MucAlreadyJoinedException, SmackException.NotConnectedException, MultiUserChatException.MissingMucCreationAcknowledgeException, MultiUserChatException.NotAMucServiceException { + muc.create(resourceName); + Form configForm = muc.getConfigurationForm(); + FillableForm answerForm = configForm.getFillableForm(); + answerForm.setAnswer("muc#roomconfig_passwordprotectedroom", true); + answerForm.setAnswer("muc#roomconfig_roomsecret", password); + muc.sendConfigurationForm(answerForm); + } + + static void createLockedMuc(MultiUserChat muc, Resourcepart resourceName) throws + SmackException.NoResponseException, XMPPException.XMPPErrorException, + InterruptedException, MultiUserChatException.MucAlreadyJoinedException, + SmackException.NotConnectedException, + MultiUserChatException.MissingMucCreationAcknowledgeException, + MultiUserChatException.NotAMucServiceException { + muc.create(resourceName); + // Note the absence of handle.makeInstant() here. The room is still being created at this point, until a + // configuration is set. + } + + static void setMaxUsers(MultiUserChat muc, int maxUsers) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, InterruptedException, SmackException.NotConnectedException { + Form configForm = muc.getConfigurationForm(); + FillableForm answerForm = configForm.getFillableForm(); + answerForm.setAnswer("muc#roomconfig_maxusers", maxUsers); + muc.sendConfigurationForm(answerForm); + } + + static void setPublicLogging(MultiUserChat muc, boolean publicLogging) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, InterruptedException, SmackException.NotConnectedException { + Form configForm = muc.getConfigurationForm(); + FillableForm answerForm = configForm.getFillableForm(); + answerForm.setAnswer("muc#roomconfig_enablelogging", publicLogging); + muc.sendConfigurationForm(answerForm); + } } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java index 30b052466..0a8dcf175 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java @@ -22,6 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.List; import java.util.Map; import org.jivesoftware.smack.SmackException; @@ -30,11 +31,13 @@ import org.jivesoftware.smack.packet.StanzaError; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverItems; +import org.jivesoftware.smackx.muc.packet.MUCInitialPresence; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; import org.igniterealtime.smack.inttest.annotations.SpecificationReference; + import org.jxmpp.jid.DomainBareJid; import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityFullJid; @@ -49,6 +52,21 @@ public class MultiUserChatEntityIntegrationTest extends AbstractMultiUserChatInt super(environment); } + /** + * Asserts that a MUC service can be discovered. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "6.1", quote = + "An entity often discovers a MUC service by sending a Service Discovery items (\"disco#items\") request to " + + "its own server. The server then returns the services that are associated with it.") + public void mucTestForDiscoveringMuc() throws Exception { + // This repeats some logic from the `AbstractMultiUserChatIntegrationTest` constructor, but is preserved here + // as an explicit test, because that might not always be true. + List services = ServiceDiscoveryManager.getInstanceFor(conOne).findServices(MUCInitialPresence.NAMESPACE, true, false); + assertFalse(services.isEmpty(), "Expected to be able to find MUC services on the domain that '" + conOne.getUser() + "' is connecting to (but could not)."); + } + /** * Asserts that a MUC service can have its features discovered. * @@ -56,13 +74,12 @@ public class MultiUserChatEntityIntegrationTest extends AbstractMultiUserChatInt */ @SmackIntegrationTest(section = "6.2", quote = "An entity may wish to discover if a service implements the Multi-User Chat protocol; in order to do so, it " + - "sends a service discovery information (\"disco#info\") query to the MUC service's JID. The service MUST " + - "return its identity and the features it supports.") + "sends a service discovery information (\"disco#info\") query to the MUC service's JID. The service MUST " + + "return its identity and the features it supports.") public void mucTestForDiscoveringFeatures() throws Exception { - final DomainBareJid mucServiceAddress = mucManagerOne.getMucServiceDomains().get(0); - DiscoverInfo info = mucManagerOne.getMucServiceDiscoInfo(mucServiceAddress); - assertFalse(info.getIdentities().isEmpty(), "Expected the service discovery information for service " + mucServiceAddress + " to include identities (but it did not)."); - assertFalse(info.getFeatures().isEmpty(), "Expected the service discovery information for service " + mucServiceAddress + " to include features (but it did not)."); + DiscoverInfo info = ServiceDiscoveryManager.getInstanceFor(conOne).discoverInfo(mucService); + assertFalse(info.getIdentities().isEmpty(), "Expected the service discovery information for service " + mucService + " to include identities (but it did not)."); + assertFalse(info.getFeatures().isEmpty(), "Expected the service discovery information for service " + mucService + " to include features (but it did not)."); } /** @@ -120,6 +137,7 @@ public class MultiUserChatEntityIntegrationTest extends AbstractMultiUserChatInt assertFalse(discoInfo.getIdentities().isEmpty(), "Expected the service discovery information for room " + mucAddress + " to include identities (but it did not)."); assertFalse(discoInfo.getFeatures().isEmpty(), "Expected the service discovery information for room " + mucAddress + " to include features (but it did not)."); + assertTrue(discoInfo.getFeatures().stream().anyMatch(feature -> MultiUserChatConstants.NAMESPACE.equals(feature.getVar())), "Expected the service discovery information for room " + mucAddress + " to include the '" + MultiUserChatConstants.NAMESPACE + "' feature (but it did not)."); } /** diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java index 930bbaf00..421109a00 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java @@ -17,9 +17,7 @@ package org.jivesoftware.smackx.muc; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.concurrent.TimeoutException; @@ -27,9 +25,6 @@ import org.jivesoftware.smack.MessageListener; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.Message; -import org.jivesoftware.smack.packet.Presence; - -import org.jivesoftware.smackx.muc.packet.MUCUser; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.TestNotPossibleException; @@ -48,62 +43,6 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati super(environment); } - /** - * Asserts that when a user joins a room, they are themselves included on the list of users notified (self-presence). - * - * @throws Exception when errors occur - */ - @SmackIntegrationTest(section = "7.2.2", quote = - "... the service MUST also send presence from the new participant's occupant JID to the full JIDs of all the " + - "occupants (including the new occupant)") - public void mucJoinTest() throws Exception { - EntityBareJid mucAddress = getRandomRoom("smack-inttest-join"); - - MultiUserChat muc = mucManagerOne.getMultiUserChat(mucAddress); - try { - Presence reflectedJoinPresence = muc.join(Resourcepart.from("nick-one")); - - MUCUser mucUser = MUCUser.from(reflectedJoinPresence); - - assertNotNull(mucUser, "Expected, but unable, to create a MUCUser instance from reflected join presence: " + reflectedJoinPresence); - assertTrue(mucUser.getStatus().contains(MUCUser.Status.PRESENCE_TO_SELF_110), "Expected the reflected join presence of " + conOne.getUser() + " of room " + mucAddress + " to include 'presence-to-self' (" + MUCUser.Status.PRESENCE_TO_SELF_110 + ") but it did not."); - assertEquals(mucAddress + "/nick-one", reflectedJoinPresence.getFrom().toString(), "Unexpected 'from' attribute value in the reflected join presence of " + conOne.getUser() + " of room " + mucAddress); - assertEquals(conOne.getUser().asEntityFullJidIfPossible().toString(), reflectedJoinPresence.getTo().toString(), "Unexpected 'to' attribute value in the reflected join presence of " + conOne.getUser() + " of room " + mucAddress); - } finally { - tryDestroy(muc); - } - } - - /** - * Asserts that when a user leaves a room, they are themselves included on the list of users notified (self-presence). - * - * @throws Exception when errors occur - */ - @SmackIntegrationTest(section = "7.14", quote = - "The service MUST then send a presence stanzas of type \"unavailable\" from the departing user's occupant " + - "JID to the departing occupant's full JIDs, including a status code of \"110\" to indicate that this " + - "notification is \"self-presence\"") - public void mucLeaveTest() throws Exception { - EntityBareJid mucAddress = getRandomRoom("smack-inttest-leave"); - - MultiUserChat muc = mucManagerOne.getMultiUserChat(mucAddress); - try { - muc.join(Resourcepart.from("nick-one")); - - Presence reflectedLeavePresence = muc.leave(); - - MUCUser mucUser = MUCUser.from(reflectedLeavePresence); - assertNotNull(mucUser, "Expected, but unable, to create a MUCUser instance from reflected leave presence: " + reflectedLeavePresence); - - assertTrue(mucUser.getStatus().contains(MUCUser.Status.PRESENCE_TO_SELF_110), "Expected the reflected leave presence of " + conOne.getUser() + " of room " + mucAddress + " to include 'presence-to-self' (" + MUCUser.Status.PRESENCE_TO_SELF_110 + ") but it did not."); - assertEquals(mucAddress + "/nick-one", reflectedLeavePresence.getFrom().toString(), "Unexpected 'from' attribute value in the reflected leave presence of " + conOne.getUser() + " of room " + mucAddress); - assertEquals(conOne.getUser().asEntityFullJidIfPossible().toString(), reflectedLeavePresence.getTo().toString(), "Unexpected 'to' attribute value in the reflected leave presence of " + conOne.getUser() + " of room " + mucAddress); - } finally { - muc.join(Resourcepart.from("nick-one")); // We need to be in the room to destroy the room - tryDestroy(muc); - } - } - @SmackIntegrationTest public void mucTest() throws Exception { EntityBareJid mucAddress = getRandomRoom("smack-inttest-message"); @@ -150,7 +89,7 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati EntityBareJid mucAddress = getRandomRoom("smack-inttest-destroy"); MultiUserChat muc = mucManagerOne.getMultiUserChat(mucAddress); - muc.join(Resourcepart.from("nick-one")); + createMuc(muc, Resourcepart.from("one-" + randomString)); final SimpleResultSyncPoint mucDestroyed = new SimpleResultSyncPoint(); @@ -165,8 +104,8 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati muc.addUserStatusListener(userStatusListener); // These would be a test implementation bug, not assertion failure. - if (mucManagerOne.getJoinedRooms().size() != 1) { - throw new IllegalStateException("Expected user to have joined a room."); + if (mucManagerOne.getJoinedRooms().stream().noneMatch(room -> room.equals(mucAddress))) { + throw new IllegalStateException("Expected user to have joined a room '" + mucAddress + "' (but does not appear to have done so)."); } try { diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java new file mode 100644 index 000000000..1125e320d --- /dev/null +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java @@ -0,0 +1,1102 @@ +/** + * + * Copyright 2015-2020 Florian Schmaus, 2021 Dan Caseley + * + * 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.muc; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeoutException; +import java.util.stream.Collectors; + +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.Presence; +import org.jivesoftware.smack.packet.StanzaError; +import org.jivesoftware.smack.sm.predicates.ForEveryMessage; +import org.jivesoftware.smack.util.StringUtils; +import org.jivesoftware.smackx.muc.packet.MUCItem; +import org.jivesoftware.smackx.muc.packet.MUCUser; + +import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; +import org.igniterealtime.smack.inttest.TestNotPossibleException; +import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; +import org.igniterealtime.smack.inttest.util.MultiResultSyncPoint; +import org.igniterealtime.smack.inttest.util.ResultSyncPoint; +import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; +import org.jxmpp.jid.EntityBareJid; +import org.jxmpp.jid.EntityFullJid; +import org.jxmpp.jid.impl.JidCreate; +import org.jxmpp.jid.parts.Resourcepart; + +@SpecificationReference(document = "XEP-0045") +public class MultiUserChatOccupantIntegrationTest extends AbstractMultiUserChatIntegrationTest { + + public MultiUserChatOccupantIntegrationTest(SmackIntegrationTestEnvironment environment) + throws SmackException.NoResponseException, XMPPException.XMPPErrorException, + SmackException.NotConnectedException, InterruptedException, TestNotPossibleException { + super(environment); + } + + /** + * Asserts that when a user joins a room, all events are received, and in the correct order. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "7.1 & 7.2.2", quote = "" + + "§ 7.1 The order of events involved in joining a room needs to be consistent so that clients can know which events to expect when. After a client sends presence to join a room, the MUC service MUST send it events in the following order: 1. In-room presence from other occupants 2. In-room presence from the joining entity itself (so-called \"self-presence\") 3. Room history (if any) 4. The room subject [...]" + + "§ 7.2.2 This self-presence MUST NOT be sent to the new occupant until the room has sent the presence of all other occupants to the new occupant ... The service MUST first send the complete list of the existing occupants to the new occupant and only then send the new occupant's own presence to the new occupant") + public void mucJoinEventOrderingTest() throws Exception { + EntityBareJid mucAddress = getRandomRoom("smack-inttest-eventordering"); + final String mucSubject = "Subject smack-inttest-eventordering " + randomString; + final String mucMessage = "Message smack-inttest-eventordering " + randomString; + + MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); + + final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString); + final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); + + createMuc(mucAsSeenByOne, nicknameOne); + mucAsSeenByOne.changeSubject(mucSubject); // Blocks until confirmed. + + // Send and wait for the message to have been reflected, so that we can be sure it's part of the MUC history. + final SimpleResultSyncPoint messageReflectionSyncPoint = new SimpleResultSyncPoint(); + mucAsSeenByOne.addMessageListener(message -> { + if (message.getBody().equals(mucMessage)) { + messageReflectionSyncPoint.signal(); + } + }); + + mucAsSeenByOne.sendMessage(mucMessage); + messageReflectionSyncPoint.waitForResult(timeout); + + final ResultSyncPoint subjectResultSyncPoint = new ResultSyncPoint<>(); + List results = new ArrayList<>(); + + mucAsSeenByTwo.addMessageListener(message -> { + String body = message.getBody(); + if (mucMessage.equals(body)) { + results.add(body); + } + }); + + mucAsSeenByTwo.addParticipantStatusListener(new ParticipantStatusListener() { + @Override public void joined(EntityFullJid participant) { + // Ignore self-presence, but record all other participants. + final EntityFullJid participantTwo = JidCreate.entityFullFrom(mucAddress, nicknameTwo); + if (!participantTwo.equals(participant)) { + results.add(participant); + } + } + }); + + mucAsSeenByTwo.addSubjectUpdatedListener((subject, from) -> { + results.add(subject); + subjectResultSyncPoint.signal(subject); + }); + + try { + Presence reflectedJoinPresence = mucAsSeenByTwo.join(nicknameTwo); + results.add(reflectedJoinPresence.getFrom()); // Self-presence should be second + + subjectResultSyncPoint.waitForResult(timeout); // Wait for subject, as it should be 4th (last) + + assertEquals(4, results.size(), "Unexpected amount of stanzas received by '" + conTwo.getUser() + "' after it joined room '" + mucAddress + "'."); + assertEquals(JidCreate.fullFrom(mucAddress, nicknameOne), results.get(0), "Unexpected 'from' address of the first stanza that was received by '" + conTwo.getUser() + "' after it joined room '" + mucAddress + "'."); + assertEquals(JidCreate.fullFrom(mucAddress, nicknameTwo), results.get(1), "Unexpected 'from' address of the seconds stanza that was received by '" + conTwo.getUser() + "' after it joined room '" + mucAddress + "'."); + assertEquals(mucMessage, results.get(2), "The third stanza that was received by '" + conTwo.getUser() + "' after it joined room '" + mucAddress + "' was expected to be a different stanza."); + assertEquals(mucSubject, results.get(3), "The fourth stanza that was received by '" + conTwo.getUser() + "' after it joined room '" + mucAddress + "' was expected to be a different stanza."); + } finally { + tryDestroy(mucAsSeenByOne); + } + } + + /** + * Asserts that when a user sends a message to a room without joining, they receive an error and the message is not + * sent to the occupants. + * + *

From XEP-0045 § 7.2.1:

+ *
+ * In order to participate in the discussions held in a multi-user chat room, a user MUST first become an occupant + * by entering the room + *
+ * + *

From XEP-0045 § 7.4:

+ *
+ * If the sender is not an occupant of the room, the service SHOULD return a <not-acceptable/> error to the + * sender and SHOULD NOT reflect the message to all occupants + *
+ * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "7.2.1 & 7.4", quote = + "§ 7.2.1: In order to participate in the discussions held in a multi-user chat room, a user MUST first become an occupant by entering the room [...] " + + "§ 7.4: If the sender is not an occupant of the room, the service SHOULD return a error to the sender and SHOULD NOT reflect the message to all occupants") + public void mucSendBeforeJoiningTest() throws Exception { + EntityBareJid mucAddress = getRandomRoom("smack-inttest-send-without-joining"); + + MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); + + createMuc(mucAsSeenByOne, Resourcepart.from("one-" + randomString)); + + ResultSyncPoint errorMessageResultSyncPoint = new ResultSyncPoint<>(); + conTwo.addStanzaListener(packet -> errorMessageResultSyncPoint.signal((Message) packet), ForEveryMessage.INSTANCE); + + ResultSyncPoint distributedMessageResultSyncPoint = new ResultSyncPoint<>(); + mucAsSeenByOne.addMessageListener(distributedMessageResultSyncPoint::signal); + + try { + mucAsSeenByTwo.sendMessage("Message without Joining"); + Message response = assertResult(errorMessageResultSyncPoint, "Expected an error to be returned to '" + conTwo.getUser() + "' after it sent a message to room '" + mucAddress + "' without joining it first (but no error was returned)."); + assertEquals(StanzaError.Condition.not_acceptable, response.getError().getCondition(), "Unexpected error condition in the (expected) error that was returned to '" + conTwo.getUser() + "' after it sent a message to room '" + mucAddress + "' without joining it first."); + assertThrows(TimeoutException.class, () -> distributedMessageResultSyncPoint.waitForResult(1000), "Occupant '" + conOne.getUser() + "' should NOT have seen the message that was sent by '" + conTwo.getUser() + "' to room '" + mucAddress + "' without the sender have joined the room (but the message was observed by the occupant)."); + } finally { + tryDestroy(mucAsSeenByOne); + } + } + + /** + * Asserts that when a user joins a room, they are sent presence information about existing participants and + * themselves that includes role and affiliation information and appropriate status codes. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "7.2.2", quote = + "If the service is able to add the user to the room, it MUST send presence from all the existing participants' " + + "occupant JIDs to the new occupant's full JID, including extended presence information about roles in a " + + "single element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an " + + " child with the 'role' attribute set to a value of \"moderator\", \"participant\", or \"visitor\", " + + "and with the 'affiliation' attribute set to a value of \"owner\", \"admin\", \"member\", or \"none\" as " + + "appropriate. [...] the \"self-presence\" sent by the room to the new user MUST include a status code of 110 " + + "so that the user knows this presence refers to itself as an occupant [...] The service MUST first send the " + + "complete list of the existing occupants to the new occupant and only then send the new occupant's own " + + "presence to the new occupant.") + public void mucJoinPresenceInformationTest() throws Exception { + EntityBareJid mucAddress = getRandomRoom("smack-inttest-presenceinfo"); + + MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByThree = mucManagerThree.getMultiUserChat(mucAddress); + + final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString); + final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); + final Resourcepart nicknameThree = Resourcepart.from("three-" + randomString); + + createMuc(mucAsSeenByOne, nicknameOne); + mucAsSeenByTwo.join(nicknameTwo); + + SimpleResultSyncPoint oneSeesTwo = new SimpleResultSyncPoint(); + mucAsSeenByOne.addParticipantListener(presence -> { + if (nicknameTwo.equals(presence.getFrom().getResourceOrEmpty())) { + oneSeesTwo.signal(); + } + }); + mucAsSeenByOne.grantModerator(nicknameTwo); + oneSeesTwo.waitForResult(timeout); + + List results = new ArrayList<>(); + mucAsSeenByThree.addParticipantListener(results::add); + + try { + // Will block until all self-presence is received, prior to which all others presences will have been received. + mucAsSeenByThree.join(nicknameThree); + + assertEquals(3, results.size(), "Unexpected amount of occupants seen by '" + conThree + "' in room '" + mucAddress + "' after joining."); // The 3rd will be self-presence. + assertNotNull(MUCUser.from(results.get(0)), "Expected to be able to parse a MUC occupant from '" + results.get(0) + "', but could not. Its syntax is likely incorrect."); // Smack implementation guarantees the "x" element and muc#user namespace + + // The order of all but the last presence (which should be the self-presence) is unpredictable. + MUCItem mucItemSelf = MUCUser.from(results.get(2)).getItem(); + Set others = new HashSet<>(); + others.add(MUCUser.from(results.get(0)).getItem()); + others.add(MUCUser.from(results.get(1)).getItem()); + + assertEquals(MUCAffiliation.none, mucItemSelf.getAffiliation(), "Unexpected MUC affiliation in reflected self-presence of '" + conThree.getUser() + "' joining room '" + mucAddress + "'."); + assertEquals(1, others.stream().filter(item -> MUCAffiliation.owner.equals(item.getAffiliation())).count(), "Unexpected amount of other occupants in room '" + mucAddress + "' (as observed by '" + conThree.getUser() + "') that have the 'owner' affiliation."); + assertEquals(1, others.stream().filter(item -> MUCAffiliation.none.equals(item.getAffiliation())).count(), "Unexpected amount of other occupants in room '" + mucAddress + "' (as observed by '" + conThree.getUser() + "') that have no affiliation."); + + assertEquals(MUCRole.participant, mucItemSelf.getRole(), "Unexpected MUC role in reflected self-presence of '" + conThree.getUser() + "' joining room '" + mucAddress + "'."); + assertEquals(2, others.stream().filter(item -> MUCRole.moderator.equals(item.getRole())).count(), "Unexpected amount of other occupants in room '" + mucAddress + "' (as observed by '" + conThree.getUser() + "') that have the 'moderator' role."); + + assertTrue(MUCUser.from(results.get(2)).getStatus().contains(MUCUser.Status.PRESENCE_TO_SELF_110), "Expected to find status '" + MUCUser.Status.PRESENCE_TO_SELF_110 + "' in reflected self-presence of '" + conThree.getUser() + "' joining room '" + mucAddress + "' (but did not)."); + } finally { + tryDestroy(mucAsSeenByOne); + } + } + + /** + * Asserts that when a user joins a room, all users are sent presence information about the new participant. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "7.2.2", quote = + "the service MUST also send presence from the new participant's occupant JID to the full JIDs of all the " + + "occupants (including the new occupant)") + public void mucJoinPresenceBroadcastTest() throws Exception { + EntityBareJid mucAddress = getRandomRoom("smack-inttest-presenceinfo"); + + MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByThree = mucManagerThree.getMultiUserChat(mucAddress); + + final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString); + final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); + final Resourcepart nicknameThree = Resourcepart.from("three-" + randomString); + + createMuc(mucAsSeenByOne, nicknameOne); + mucAsSeenByTwo.join(nicknameTwo); + + final MultiResultSyncPoint syncPoint = new MultiResultSyncPoint<>(2); + + mucAsSeenByOne.addParticipantListener(presence -> { + if (nicknameThree.equals(presence.getFrom().getResourceOrEmpty())) { + syncPoint.signal(presence); + } + }); + + mucAsSeenByTwo.addParticipantListener(presence -> { + if (nicknameThree.equals(presence.getFrom().getResourceOrEmpty())) { + syncPoint.signal(presence); + } + }); + + try { + mucAsSeenByThree.join(nicknameThree); + + List results = syncPoint.waitForResults(timeout); + assertTrue(results.stream().allMatch( + result -> JidCreate.fullFrom(mucAddress, nicknameThree).equals(result.getFrom())), + "Expected all occupants of room '" + mucAddress + "' to be notified of '" + conThree.getUser() + "' using nickname '" + nicknameThree + "' joining the room (but one or more got notified )."); + assertTrue(results.stream().anyMatch( + result -> result.getTo().equals(conOne.getUser().asEntityFullJidIfPossible())), + "Expected '" + conOne.getUser().asEntityFullJidIfPossible() + "' to be notified of '" + conThree.getUser() + "' joining room '" + mucAddress + "' (but did not)"); + assertTrue(results.stream().anyMatch( + result -> result.getTo().equals(conTwo.getUser().asEntityFullJidIfPossible())), + "Expected '" + conTwo.getUser().asEntityFullJidIfPossible() + "' to be notified of '" + conThree.getUser() + "' joining room '" + mucAddress + "' (but did not)"); + } finally { + tryDestroy(mucAsSeenByOne); + } + } + + /** + * Asserts that when a user enters a non-anonymous room, the presence notifications contain extended presence + * information. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "7.2.3", quote = + "If the room is non-anonymous, the service MUST send the new occupant's full JID to all occupants using " + + "extended presence information in an element qualified by the 'http://jabber.org/protocol/muc#user' " + + "namespace and containing an child with a 'jid' attribute specifying the occupant's full JID. [...]" + + "If the user is entering a room that is non-anonymous (i.e., which informs all occupants of each occupant's " + + "full JID as shown above), the service MUST warn the user by including a status code of \"100\" in the " + + "initial presence that the room sends to the new occupant.") + public void mucJoinNonAnonymousRoomTest() throws Exception { + EntityBareJid mucAddress = getRandomRoom("smack-inttest-joinnonanonymousroom"); + + MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); + + final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString); + final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); + + createNonAnonymousMuc(mucAsSeenByOne, nicknameOne); + + final ResultSyncPoint participantOneSyncPoint = new ResultSyncPoint<>(); + mucAsSeenByOne.addParticipantListener(presence -> { + if (nicknameTwo.equals(presence.getFrom().getResourceOrEmpty())) { + participantOneSyncPoint.signal(presence); + } + }); + + final ResultSyncPoint participantTwoSyncPoint = new ResultSyncPoint<>(); + mucAsSeenByTwo.addParticipantListener(presence -> { + if (nicknameTwo.equals(presence.getFrom().getResourceOrEmpty())) { + participantTwoSyncPoint.signal(presence); + } + }); + + try { + mucAsSeenByTwo.join(nicknameTwo); + Presence presenceReceivedByOne = assertResult(participantOneSyncPoint, "Expected '" + conOne.getUser() + "' to receive a presence stanza after '" + conTwo.getUser() + "' joined room '" + mucAddress + "' (but did not)."); + Presence presenceReceivedByTwo = assertResult(participantTwoSyncPoint, "Expected '" + conTwo.getUser() + "' to receive a presence stanza after they themselves joined room '" + mucAddress + "' (but did not)."); + + // Check the presence received by participant one for inclusion of full jid of participant two + MUCUser announcedParticipantTwoUser = MUCUser.from(presenceReceivedByOne); + assertNotNull(announcedParticipantTwoUser, "Expected to be able to parse a MUC occupant from '" + presenceReceivedByOne + "', but could not. Its syntax is likely incorrect."); // Smack implementation guarantees the "x" element and muc#user namespace + assertNotNull(announcedParticipantTwoUser.getItem(), "Expected to be able to parse a MUC occupant item from '" + presenceReceivedByOne + "', but could not. Its syntax is likely incorrect."); + assertEquals(conTwo.getUser().asEntityFullJidOrThrow(), announcedParticipantTwoUser.getItem().getJid(), "Expected extended presence information received by '" + conOne.getUser() + "' after '" + conTwo.getUser() + "' joined room '" + mucAddress + "' to include their full JID."); + + // Check the presence received by participant two for inclusion of status 100 + assertTrue(MUCUser.from(presenceReceivedByTwo).getStatus().stream().anyMatch(status -> 100 == status.getCode()), + "Expected to find status '100' in reflected self-presence of '" + conTwo.getUser() + "' joining room '" + mucAddress + "' (but did not)."); + + } finally { + tryDestroy(mucAsSeenByOne); + } + } + + /** + * Asserts that when a user enters a semi-anonymous room, the presence notifications received by occupants that + * are not a moderator does not contain extended presence information. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "7.2.4", quote = + "If the room is semi-anonymous, the service MUST send presence from the new occupant to all occupants as " + + "specified above (i.e., unless the room is configured to not broadcast presence from new occupants below a " + + "certain affiliation level as controlled by the \"muc#roomconfig_presencebroadcast\" room configuration " + + "option), but MUST include the new occupant's full JID only in the presence notifications it sends to " + + "occupants with a role of \"moderator\" and not to non-moderator occupants.") + public void mucJoinSemiAnonymousRoomReceivedByNonModeratorTest() throws Exception { + EntityBareJid mucAddress = getRandomRoom("smack-inttest-joinsemianonymousroom"); + + MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByThree = mucManagerThree.getMultiUserChat(mucAddress); + + final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString); + final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); + final Resourcepart nicknameThree = Resourcepart.from("three-" + randomString); + + createSemiAnonymousMuc(mucAsSeenByOne, nicknameOne); + + mucAsSeenByTwo.join(nicknameTwo); + + // First pass: participant two is not a moderator yet + final ResultSyncPoint participantTwoSyncPoint = new ResultSyncPoint<>(); + mucAsSeenByTwo.addParticipantListener(presence -> { + if (nicknameThree.equals(presence.getFrom().getResourceOrEmpty())) { + participantTwoSyncPoint.signal(presence); + } + }); + + try { + mucAsSeenByThree.join(nicknameThree); + Presence presenceReceivedByTwo = assertResult(participantTwoSyncPoint, "Expected '" + conTwo.getUser() + "' to receive presence when '" + conThree.getUser() + "' joined room '" + mucAddress + "' (but did not)."); + + // Check the presence received by participant two for exclusion of full jid of participant three + assertNull(MUCUser.from(presenceReceivedByTwo).getItem().getJid(), "Did not expect '" + conTwo.getUser() + "' (who is not a moderator at this stage) to receive the full JID of '" + conThree.getUser() + "' when they joined room '" + mucAddress + "' (but they did)."); + } finally { + mucAsSeenByThree.leave(); // Reset to have a second go + } + } + + /** + * Asserts that when a user enters a semi-anonymous room, the presence notifications contain extended presence + * information when sent to moderators. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "7.2.4", quote = + "If the room is semi-anonymous, the service MUST send presence from the new occupant to all occupants as " + + "specified above (i.e., unless the room is configured to not broadcast presence from new occupants below a " + + "certain affiliation level as controlled by the \"muc#roomconfig_presencebroadcast\" room configuration " + + "option), but MUST include the new occupant's full JID only in the presence notifications it sends to " + + "occupants with a role of \"moderator\" and not to non-moderator occupants.") + public void mucJoinSemiAnonymousRoomReceivedByModeratorTest() throws Exception { + EntityBareJid mucAddress = getRandomRoom("smack-inttest-joinsemianonymousroom"); + + MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByThree = mucManagerThree.getMultiUserChat(mucAddress); + + final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString); + final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); + final Resourcepart nicknameThree = Resourcepart.from("three-" + randomString); + + // Second pass: participant two is now a moderator + createSemiAnonymousMuc(mucAsSeenByOne, nicknameOne); + mucAsSeenByTwo.join(nicknameTwo); + + mucAsSeenByOne.grantModerator(nicknameTwo); + final ResultSyncPoint participantTwoSyncPoint = new ResultSyncPoint<>(); + mucAsSeenByTwo.addParticipantListener(presence -> { + if (nicknameThree.equals(presence.getFrom().getResourceOrEmpty())) { + participantTwoSyncPoint.signal(presence); + } + }); + + try { + mucAsSeenByThree.join(nicknameThree); + Presence presenceReceivedByTwo = assertResult(participantTwoSyncPoint, "Expected '" + conTwo.getUser() + "' to receive presence when '" + conThree.getUser() + "' joined room '" + mucAddress + "' (but did not)."); + + // Check the presence received by participant two for inclusion of full jid of participant three + MUCUser announcedParticipantThreeUser = MUCUser.from(presenceReceivedByTwo); + assertEquals(conThree.getUser().asEntityFullJidOrThrow(), announcedParticipantThreeUser.getItem().getJid(), "Expected '" + conTwo.getUser() + "' (who is a moderator at this stage) to receive the full JID of '" + conThree.getUser() + "' when they joined room '" + mucAddress + "' (but they did not)."); + } finally { + tryDestroy(mucAsSeenByOne); + } + } + + /** + * Asserts that a user can not enter a password-protected room without supplying a password. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "7.2.5", quote = + "If the room requires a password and the user did not supply one (or the password provided is incorrect), the " + + "service MUST deny access to the room and inform the user that they are unauthorized; this is done by returning " + + "a presence stanza of type \"error\" specifying a error.") + public void mucJoinPasswordProtectedWithoutPasswordRoomTest() throws Exception { + EntityBareJid mucAddress = getRandomRoom("smack-inttest-enterpasswordprotectedroom"); + + MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); + + final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString); + final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); + + final String correctPassword = StringUtils.insecureRandomString(8); + + createPasswordProtectedMuc(mucAsSeenByOne, nicknameOne, correctPassword); + + try { + // First try: no password + XMPPException.XMPPErrorException noPasswordErrorException = assertThrows( + XMPPException.XMPPErrorException.class, () -> mucAsSeenByTwo.join(nicknameTwo), + "Expected an error to be returned when '" + conTwo.getUser() + "' attempted to join password-protected room '" + mucAddress + "' without a password."); + assertNotNull(noPasswordErrorException.getStanzaError(), + "Expected an error to be returned when '" + conTwo.getUser() + "' attempted to join password-protected room '" + mucAddress + "' without a password."); + assertEquals(StanzaError.Condition.not_authorized, noPasswordErrorException.getStanzaError().getCondition(), + "Unexpected condition in the (expected) error that was returned when '" + conTwo.getUser() + "' attempted to join password-protected room '" + mucAddress + "' without a password."); + } finally { + mucAsSeenByOne.destroy(); + } + } + + /** + * Asserts that a user can not enter a password-protected room without supplying the correct password. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "7.2.5", quote = + "If the room requires a password and the user did not supply one (or the password provided is incorrect), the " + + "service MUST deny access to the room and inform the user that they are unauthorized; this is done by returning " + + "a presence stanza of type \"error\" specifying a error.") + public void mucJoinPasswordProtectedRoomWrongPasswordTest() throws Exception { + EntityBareJid mucAddress = getRandomRoom("smack-inttest-enterpasswordprotectedroom"); + + MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); + + final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString); + final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); + + final String correctPassword = StringUtils.insecureRandomString(8); + + createPasswordProtectedMuc(mucAsSeenByOne, nicknameOne, correctPassword); + + try { + // Second try: wrong password + XMPPException.XMPPErrorException wrongPasswordErrorException = assertThrows( + XMPPException.XMPPErrorException.class, + () -> mucAsSeenByTwo.join(nicknameTwo, correctPassword + "_"), + "Expected an error to be returned when '" + conTwo.getUser() + "' attempted to join password-protected room '" + mucAddress + "' using an incorrect password."); + assertNotNull(wrongPasswordErrorException.getStanzaError(), + "Expected an error to be returned when '" + conTwo.getUser() + "' attempted to join password-protected room '" + mucAddress + "' using an incorrect password."); + assertEquals(StanzaError.Condition.not_authorized, wrongPasswordErrorException.getStanzaError().getCondition(), + "Unexpected condition in the (expected) error that was returned when '" + conTwo.getUser() + "' attempted to join password-protected room '" + mucAddress + "' using an incorrect password."); + } finally { + mucAsSeenByOne.destroy(); + } + } + + /** + * Asserts that a user can enter a password-protected room when supplying the correct password. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "7.2.5", quote = + "If the room requires a password and the user did not supply one (or the password provided is incorrect), the " + + "service MUST deny access to the room and inform the user that they are unauthorized; this is done by returning " + + "a presence stanza of type \"error\" specifying a error.") + public void mucJoinPasswordProtectedRoomCorrectPasswordTest() throws Exception { + EntityBareJid mucAddress = getRandomRoom("smack-inttest-enterpasswordprotectedroom"); + + MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); + + final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString); + final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); + + final String correctPassword = StringUtils.insecureRandomString(8); + + createPasswordProtectedMuc(mucAsSeenByOne, nicknameOne, correctPassword); + + // Set up to receive presence responses on successful join + final ResultSyncPoint participantTwoSyncPoint = new ResultSyncPoint<>(); + mucAsSeenByTwo.addParticipantListener(presence -> { + if (nicknameTwo.equals(presence.getFrom().getResourceOrEmpty())) { + participantTwoSyncPoint.signal(presence); + } + }); + + try { + // Third try: correct password + mucAsSeenByTwo.join(nicknameTwo, correctPassword); + Presence presenceCorrectPassword = assertResult(participantTwoSyncPoint, "Expected '" + conTwo.getUser() + "' to be able to join password-protected room '" + mucAddress + "' using the correct password (but no join-presence was received)."); + assertNull(presenceCorrectPassword.getError(), "Unexpected error in join-presence of '" + conTwo.getUser() + "' after joining password-protected room '" + mucAddress + "' using the correct password: " + presenceCorrectPassword.getError()); + } finally { + mucAsSeenByOne.destroy(); + } + } + + /** + * Asserts that a user can not enter a members-only room while not being a member. + * + * This test does not cover § 9.3, aka the happy path. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "7.2.6", quote = + "If the room is members-only but the user is not on the member list, the service MUST deny access to the " + + "room and inform the user that they are not allowed to enter the room; this is done by returning a presence " + + "stanza of type \"error\" specifying a error condition.") + public void mucJoinMembersOnlyRoomTest() throws Exception { + EntityBareJid mucAddress = getRandomRoom("smack-inttest-entermembersonlyroom"); + + MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); + + final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString); + final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); + + createMembersOnlyMuc(mucAsSeenByOne, nicknameOne); + + try { + XMPPException.XMPPErrorException registrationRequiredErrorException = assertThrows( + XMPPException.XMPPErrorException.class, () -> mucAsSeenByTwo.join(nicknameTwo), + "Expected an error to be returned when non-member '" + conTwo.getUser() + "' tries to join member-online room '" + mucAddress + "' (but an error was not returned)."); + assertNotNull(registrationRequiredErrorException, "Expected an error to be returned when non-member '" + conTwo.getUser() + "' tries to join member-online room '" + mucAddress + "' (but an error was not returned)."); + assertNotNull(registrationRequiredErrorException.getStanzaError(), "Expected an error to be returned when non-member '" + conTwo.getUser() + "' tries to join member-online room '" + mucAddress + "' (but an error was not returned)."); + assertEquals(StanzaError.Condition.registration_required, registrationRequiredErrorException.getStanzaError().getCondition(), + "Unexpected condition in the (expected) error that was returned when non-member '" + conTwo.getUser() + "' joined member-online room '" + mucAddress + "' (."); + } finally { + mucAsSeenByOne.destroy(); + } + } + + /** + * Asserts that a user can not enter a room while being banned. + * + *

From XEP-0045 § 7.2.7:

+ *
+ * + *
+ * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "7.2.7", quote = + "If the user has been banned from the room (i.e., has an affiliation of \"outcast\"), the service MUST deny " + + "access to the room and inform the user of the fact that they are banned; this is done by returning a presence " + + "stanza of type \"error\" specifying a error condition.") + public void mucBannedUserJoinRoomTest() throws Exception { + EntityBareJid mucAddress = getRandomRoom("smack-inttest-banneduser"); + + MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); + + final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString); + final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); + + createMuc(mucAsSeenByOne, nicknameOne); + + mucAsSeenByOne.banUser(conTwo.getUser().asBareJid(), "Insufficient witchcraft"); + + try { + XMPPException.XMPPErrorException forbiddenErrorException = assertThrows( + XMPPException.XMPPErrorException.class, () -> mucAsSeenByTwo.join(nicknameTwo), + "Expected an error to be returned when outcast '" + conTwo.getUser() + "' tries to join room '" + mucAddress + "' (but an error was not returned)."); + assertNotNull(forbiddenErrorException, "Expected an error to be returned when outcast '" + conTwo.getUser() + "' tries to join room '" + mucAddress + "' (but an error was not returned)."); + assertNotNull(forbiddenErrorException.getStanzaError(), "Expected an error to be returned when outcast '" + conTwo.getUser() + "' tries to join room '" + mucAddress + "' (but an error was not returned)."); + assertEquals(StanzaError.Condition.forbidden, forbiddenErrorException.getStanzaError().getCondition(), + "Unexpected condition in the (expected) error to was returned when outcast '" + conTwo.getUser() + "' tried to join room '" + mucAddress + "'."); + } finally { + mucAsSeenByOne.destroy(); + } + } + + /** + * Asserts that a user can not enter a room with the same nickname as another user who is already present. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "7.2.8", quote = + "If the room already contains another user with the nickname desired by the user seeking to enter the room " + + "(or if the nickname is reserved by another user on the member list), the service MUST deny access to the " + + "room and inform the user of the conflict; this is done by returning a presence stanza of type \"error\" " + + "specifying a error condition.") + public void mucNicknameConflictJoinRoomTest() throws Exception { + EntityBareJid mucAddress = getRandomRoom("smack-inttest-nicknameclash"); + + MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); + + final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString); + + createMuc(mucAsSeenByOne, nicknameOne); + + try { + XMPPException.XMPPErrorException conflictErrorException = assertThrows( + XMPPException.XMPPErrorException.class, () -> mucAsSeenByTwo.join(nicknameOne), + "Expected an error to be returned when '" + conTwo.getUser() + "' tried to join room '" + mucAddress + "' using the nickname '" + nicknameOne + "' that was already in used by another occupant of the room (but an error was not returned)."); + assertNotNull(conflictErrorException, "Expected an error to be returned when '" + conTwo.getUser() + "' tried to join room '" + mucAddress + "' using the nickname '" + nicknameOne + "' that was already in used by another occupant of the room (but an error was not returned)."); + assertNotNull(conflictErrorException.getStanzaError(), "Expected an error to be returned when '" + conTwo.getUser() + "' tried to join room '" + mucAddress + "' using the nickname '" + nicknameOne + "' that was already in used by another occupant of the room (but an error was not returned)."); + assertEquals(StanzaError.Condition.conflict, conflictErrorException.getStanzaError().getCondition(), + "Unexpected condition in the (expected) error that was returned when '" + conTwo.getUser() + "' tried to join room '" + mucAddress + "' using the nickname '" + nicknameOne + "' that was already in used by another occupant of the room."); + } finally { + mucAsSeenByOne.destroy(); + } + } + + /** + * Asserts that a room can not go past the configured maximum number of users, if a non-admin non-owner user + * attempts to join. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "7.2.9", quote = + "If the room has reached its maximum number of occupants, the service SHOULD deny access to the room and " + + "inform the user of the restriction; this is done by returning a presence stanza of type \"error\" " + + "specifying a error condition. Alternatively, the room could kick an \"idle user\" " + + "in order to free up space (where the definition of \"idle user\" is up to the implementation).") + public void mucMaxUsersLimitJoinRoomTest() throws Exception { + EntityBareJid mucAddress = getRandomRoom("smack-inttest-maxusersreached"); + + MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByThree = mucManagerThree.getMultiUserChat(mucAddress); + + final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString); + final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); + final Resourcepart nicknameThree = Resourcepart.from("three-" + randomString); + + createMuc(mucAsSeenByOne, nicknameOne); + setMaxUsers(mucAsSeenByOne, 2); + + // Set up for participant 1 to receive presence responses on join of participant 2 + final ResultSyncPoint participantOneSeesTwoSyncPoint = new ResultSyncPoint<>(); + mucAsSeenByOne.addParticipantListener(presence -> { + if (nicknameTwo.equals(presence.getFrom().getResourceOrEmpty())) { + participantOneSeesTwoSyncPoint.signal(presence); + } + }); + + // Set up for participant 3 to receive presence responses on join of participant 3 + final ResultSyncPoint participantThreeSeesThreeSyncPoint = new ResultSyncPoint<>(); + mucAsSeenByThree.addParticipantListener(presence -> { + if (nicknameThree.equals(presence.getFrom().getResourceOrEmpty())) { + participantThreeSeesThreeSyncPoint.signal(presence); + } + }); + + try { + mucAsSeenByTwo.join(nicknameTwo); + participantOneSeesTwoSyncPoint.waitForResult(timeout); + + assertEquals(2, mucAsSeenByOne.getOccupantsCount(), "Unexpected occupant count as seen by '" + conOne.getUser() + "' in room '" + mucAddress + "' (prior to the join attempt of a third occupant)."); + + // Now user 3 may or may not be able to join the room. The service can either deny access to user three, or + // it can kick user 2. Both strategies would comply with the specification. So the only thing we can + // reasonably test here is whether the room doesn't have more occupants than its max size. + + try { + mucAsSeenByThree.join(nicknameThree); + } catch (XMPPException.XMPPErrorException unavailableErrorException) { + // This exception is expected if the muc implementation employs the strategy to deny access beyond the + // maxusers value + if (unavailableErrorException.getStanzaError() == null + || !StanzaError.Condition.service_unavailable.equals( + unavailableErrorException.getStanzaError().getCondition())) { + throw unavailableErrorException; + } + } + + // Now we should wait until participant one is informed about the (probably failed) new participant three + // room join. But if joining failed, there will be no such update. All we can reasonably do is wait until + // participant three has received its own presence response. This is not watertight though. + participantThreeSeesThreeSyncPoint.waitForResult(timeout); + + // Irrespective of the way the implementation handles max users, there should still be only 2 users. + assertEquals(2, mucAsSeenByOne.getOccupantsCount(), "Unexpected occupant count as seen by '" + conOne.getUser() + "' in room '" + mucAddress + "' (after the join attempt of a third occupant)."); + + } finally { + mucAsSeenByOne.destroy(); + } + } + + /** + * Asserts that an admin can still join a room that has reached the configured maximum number of users. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "7.2.9", quote = + "If the room has reached its maximum number of occupants and a room admin or owner attempts to join, the " + + "room MUST allow the admin or owner to join, up to some reasonable number of additional occupants; this " + + "helps to prevent denial of service attacks caused by stuffing the room with non-admin users.") + public void mucMaxUsersLimitAdminCanStillJoinRoomTest() throws Exception { + EntityBareJid mucAddress = getRandomRoom("smack-inttest-maxusersreached-adminjoin"); + + MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByThree = mucManagerThree.getMultiUserChat(mucAddress); + + final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString); + final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); + final Resourcepart nicknameThree = Resourcepart.from("three-" + randomString); + + createMuc(mucAsSeenByOne, nicknameOne); + setMaxUsers(mucAsSeenByOne, 2); + + // Set up for participant 1 to receive presence responses on join of participant 2 + // Set up for participant 1 to receive presence responses on join of participant 3 + final ResultSyncPoint participantOneSeesTwoSyncPoint = new ResultSyncPoint<>(); + final ResultSyncPoint participantOneSeesThreeSyncPoint = new ResultSyncPoint<>(); + mucAsSeenByOne.addParticipantListener(presence -> { + if (nicknameTwo.equals(presence.getFrom().getResourceOrEmpty())) { + participantOneSeesTwoSyncPoint.signal(presence); + } else if (nicknameThree.equals(presence.getFrom().getResourceOrEmpty())) { + participantOneSeesThreeSyncPoint.signal(presence); + } + }); + + try { + mucAsSeenByTwo.join(nicknameTwo); + participantOneSeesTwoSyncPoint.waitForResult(timeout); + + assertEquals(2, mucAsSeenByOne.getOccupantsCount(), "Unexpected occupant count in room '" + mucAddress + "' (as observed by '" + conOne.getUser() + "') (prior to an admin attempting to join a room that was already having its maximum number of occupants)."); + + mucAsSeenByOne.grantAdmin(conThree.getUser().asBareJid()); // blocking call + mucAsSeenByThree.join(nicknameThree); + participantOneSeesThreeSyncPoint.waitForResult(timeout); + + assertNotNull(mucAsSeenByOne.getOccupant(JidCreate.entityFullFrom(mucAddress, nicknameThree)), "Expected admin '" + conThree.getUser() + "' to be in room '" + mucAddress + "' (as observed by '" + conOne.getUser() + "'), but was not."); + assertEquals(3, mucAsSeenByOne.getOccupantsCount(), "Unexpected occupant count in room '" + mucAddress + "' (as observed by '" + conOne.getUser() + "') (after an admin joined a room that was already having its maximum number of occupants)"); + } finally { + mucAsSeenByOne.destroy(); + } + } + + /** + * Asserts that an owner can still join a room that has reached the configured maximum number of users. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "7.2.9", quote = + "If the room has reached its maximum number of occupants and a room admin or owner attempts to join, the " + + "room MUST allow the admin or owner to join, up to some reasonable number of additional occupants; this " + + "helps to prevent denial of service attacks caused by stuffing the room with non-admin users.") + public void mucMaxUsersLimitOwnerCanStillJoinRoomTest() throws Exception { + EntityBareJid mucAddress = getRandomRoom("smack-inttest-maxusersreached-ownerjoin"); + + MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByThree = mucManagerThree.getMultiUserChat(mucAddress); + + final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString); + final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); + final Resourcepart nicknameThree = Resourcepart.from("three-" + randomString); + + createMuc(mucAsSeenByOne, nicknameOne); + setMaxUsers(mucAsSeenByOne, 2); + + // Set up for participant 1 to receive presence responses on join of participant 2 + // Set up for participant 1 to receive presence responses on join of participant 3 + final ResultSyncPoint participantOneSeesTwoSyncPoint = new ResultSyncPoint<>(); + final ResultSyncPoint participantOneSeesThreeSyncPoint = new ResultSyncPoint<>(); + mucAsSeenByOne.addParticipantListener(presence -> { + if (nicknameTwo.equals(presence.getFrom().getResourceOrEmpty())) { + participantOneSeesTwoSyncPoint.signal(presence); + } else if (nicknameThree.equals(presence.getFrom().getResourceOrEmpty())) { + participantOneSeesThreeSyncPoint.signal(presence); + } + }); + + try { + mucAsSeenByTwo.join(nicknameTwo); + participantOneSeesTwoSyncPoint.waitForResult(timeout); + + assertEquals(2, mucAsSeenByOne.getOccupantsCount(), "Unexpected occupant count in room '" + mucAddress + "' (as observed by '" + conOne.getUser() + "') (prior to an owner attempting to join a room that was already having its maximum number of occupants)."); + + mucAsSeenByOne.grantOwnership(conThree.getUser().asBareJid()); // blocking call + mucAsSeenByThree.join(nicknameThree); + participantOneSeesThreeSyncPoint.waitForResult(timeout); + + assertNotNull(mucAsSeenByOne.getOccupant(JidCreate.entityFullFrom(mucAddress, nicknameThree)), "Expected owner '" + conThree.getUser() + "' to be in room '" + mucAddress + "' (as observed by '" + conOne.getUser() + "'), but was not."); + assertEquals(3, mucAsSeenByOne.getOccupantsCount(), "Unexpected occupant count in room '" + mucAddress + "' (as observed by '" + conOne.getUser() + "') (after an owner joined a room that was already having its maximum number of occupants)"); + + } finally { + mucAsSeenByOne.destroy(); + } + } + + /** + * Asserts that a room can not be entered while it still being created (locked). + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "7.2.10", quote = + "If a user attempts to enter a room while it is \"locked\" (i.e., before the room creator provides an " + + "initial configuration and therefore before the room officially exists), the service MUST refuse entry and " + + "return an error to the user.") + public void mucJoinLockedRoomTest() throws Exception { + EntityBareJid mucAddress = getRandomRoom("smack-inttest-lockedroom"); + + MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); + + final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString); + final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); + + createLockedMuc(mucAsSeenByOne, nicknameOne); + + try { + XMPPException.XMPPErrorException conflictErrorException = assertThrows( + XMPPException.XMPPErrorException.class, () -> mucAsSeenByTwo.join(nicknameTwo), + "Expected an error to be returned when '" + conTwo.getUser() + "' tried to join room '" + mucAddress + "' that is still being created/is locked (but no error was returned)."); + assertNotNull(conflictErrorException, "Expected an error to be returned when '" + conTwo.getUser() + "' tried to join room '" + mucAddress + "' that is still being created/is locked (but no error was returned)."); + assertNotNull(conflictErrorException.getStanzaError(), "Expected an error to be returned when '" + conTwo.getUser() + "' tried to join room '" + mucAddress + "' that is still being created/is locked (but no error was returned)."); + assertEquals(StanzaError.Condition.item_not_found, conflictErrorException.getStanzaError().getCondition(), + "Unexpected condition in the (expected) error that was returned when '" + conTwo.getUser() + "' tried to join room '" + mucAddress + "' that is still being created/is locked."); + + } finally { + mucAsSeenByOne.destroy(); + } + } + + /** + * Asserts that a user is warned when entering a room that allows public logging. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "7.2.12", quote = + "If the user is entering a room in which the discussions are logged to a public archive (often accessible " + + "via HTTP), the service SHOULD allow the user to enter the room but MUST also warn the user that the " + + "discussions are logged. This is done by including a status code of \"170\" in the initial presence that the " + + "room sends to the new occupant.") + public void mucJoinRoomWithPublicLoggingTest() throws Exception { + final EntityBareJid mucAddress = getRandomRoom("smack-inttest-publiclogging"); + + final MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); + final MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); + + final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString); + final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); + + createMuc(mucAsSeenByOne, nicknameOne); + setPublicLogging(mucAsSeenByOne, true); + + try { + Presence twoPresence = mucAsSeenByTwo.join(nicknameTwo); + assertTrue(MUCUser.from(twoPresence).getStatus().stream().anyMatch(status -> 170 == status.getCode()), + "Expected initial presence reflected to '" + conTwo.getUser() + "' when joining room '" + mucAddress + "' to include the status code '170' (but it did not)."); + } finally { + mucAsSeenByOne.destroy(); + } + } + + /** + * Asserts that all users in a room are correctly informed about nickname change of a participant. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "7.6", quote = + "A common feature of chat rooms is the ability for an occupant to change his or her nickname within the room. " + + "In MUC this is done by sending updated presence information to the room, specifically by sending presence to " + + "a new occupant JID in the same room (changing only the resource identifier in the occupant JID). The service " + + "then sends two presence stanzas to the full JID of each occupant (including the occupant who is changing his " + + "or her room nickname), one of type \"unavailable\" for the old nickname and one indicating availability for " + + "the new nickname. The unavailable presence MUST contain the following as extended presence information in an " + + "; element qualified by the 'http://jabber.org/protocol/muc#user' namespace: - The new nickname (in this " + + "case, nick='oldhag') - A status code of 303 This enables the recipients to correlate the old roomnick with " + + "the new roomnick.\n") + public void mucChangeNicknameInformationTest() throws Exception { + EntityBareJid mucAddress = getRandomRoom("smack-inttest-changenickname"); + + MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); + + final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString); + final Resourcepart nicknameTwoOriginal = Resourcepart.from("two-original-" + randomString); + final Resourcepart nicknameTwoNew = Resourcepart.from("two-new-" + randomString); + + createMuc(mucAsSeenByOne, nicknameOne); + + SimpleResultSyncPoint participantOneSeesTwoEnter = new SimpleResultSyncPoint(); + mucAsSeenByOne.addParticipantListener(presence -> { + if (nicknameTwoOriginal.equals(presence.getFrom().getResourceOrEmpty())) { + participantOneSeesTwoEnter.signal(); + } + }); + + // Have participant two enter the room + mucAsSeenByTwo.join(nicknameTwoOriginal); + participantOneSeesTwoEnter.waitForResult(timeout); + + // Although logic dictates that the 'unavailable' presence stanzas for the old nick should precede the presence + // stanza for the new nick - the specification does not dictate that. So we should allow for the order to be + // reversed. Here we will expect an unavailable and an available presence stanza sent to both participant one + // and participant two. So that adds up to a total of four. + MultiResultSyncPoint participantTwoPresencesSyncPoint = new MultiResultSyncPoint<>(4); + mucAsSeenByOne.addParticipantListener(presence -> { + if (nicknameTwoOriginal.equals(presence.getFrom().getResourceOrEmpty()) || nicknameTwoNew.equals( + presence.getFrom().getResourceOrEmpty())) { + participantTwoPresencesSyncPoint.signal(presence); + } + }); + mucAsSeenByTwo.addParticipantListener(presence -> { + if (nicknameTwoOriginal.equals(presence.getFrom().getResourceOrEmpty()) || nicknameTwoNew.equals( + presence.getFrom().getResourceOrEmpty())) { + participantTwoPresencesSyncPoint.signal(presence); + } + }); + + try { + // Participant two changes nickname + mucAsSeenByTwo.changeNickname(nicknameTwoNew); + final List partTwoPresencesReceived = participantTwoPresencesSyncPoint.waitForResults( + timeout); + + final List unavailablePresencesReceivedByOne = partTwoPresencesReceived.stream().filter( + presence -> !presence.isAvailable()).filter( + presence -> presence.getTo().equals(conOne.getUser().asEntityFullJidIfPossible())).collect( + Collectors.toList()); + final List unavailablePresencesReceivedByTwo = partTwoPresencesReceived.stream().filter( + presence -> !presence.isAvailable()).filter( + presence -> presence.getTo().equals(conTwo.getUser().asEntityFullJidIfPossible())).collect( + Collectors.toList()); + final List availablePresencesReceivedByOne = partTwoPresencesReceived.stream().filter( + Presence::isAvailable).filter( + presence -> presence.getTo().equals(conOne.getUser().asEntityFullJidIfPossible())).collect( + Collectors.toList()); + final List availablePresencesReceivedByTwo = partTwoPresencesReceived.stream().filter( + Presence::isAvailable).filter( + presence -> presence.getTo().equals(conTwo.getUser().asEntityFullJidIfPossible())).collect( + Collectors.toList()); + + // Validate that both users received both 'available' and 'unavailable' presence stanzas + assertEquals(1, unavailablePresencesReceivedByOne.size(), "Expected '" + conOne.getUser() + "' to have received one 'unavailable' presence when '" + conTwo.getUser() + "' changed its nickname in room '" + mucAddress + "' (but did not)"); + assertEquals(1, unavailablePresencesReceivedByTwo.size(), "Expected '" + conTwo.getUser() + "' to have received one 'unavailable' presence when they changed their nickname in room '" + mucAddress + "' (but did not)"); + assertEquals(1, availablePresencesReceivedByOne.size(), "Expected '" + conOne.getUser() + "' to have received one 'available' presence when '" + conTwo.getUser() + "' changed its nickname in room '" + mucAddress + "' (but did not)"); + assertEquals(1, availablePresencesReceivedByTwo.size(), "Expected '" + conTwo.getUser() + "' to have received one 'available' presence when they changed their nickname in room '" + mucAddress + "' (but did not)"); + + // Validate that the received 'unavailable' presence stanzas contain the status and items elements as specified + assertTrue(MUCUser.from(unavailablePresencesReceivedByOne.get(0)).getStatus().stream().anyMatch(status -> 303 == status.getCode()), + "Expected the 'unavailable' presence of user '" + conTwo.getUser() + "' reflecting their nickname change in room '" + mucAddress + "' as received by '" + conOne.getUser() + "' to include status code '303' (but it did not)."); + assertEquals(nicknameTwoNew, MUCUser.from(unavailablePresencesReceivedByOne.get(0)).getItem().getNick(), + "Expected the 'unavailable' presence of user '" + conTwo.getUser() + "' reflecting their nickname change in room '" + mucAddress + "' as received by '" + conOne.getUser() + "' to include the new nickname (but it did not)."); + assertTrue(MUCUser.from(unavailablePresencesReceivedByTwo.get(0)).getStatus().stream().anyMatch(status -> 303 == status.getCode()), + "Expected the 'unavailable' presence of user '" + conTwo.getUser() + "' reflecting their nickname change in room '" + mucAddress + "' as received by themselves to include status code '303' (but it did not)."); + assertEquals(nicknameTwoNew, MUCUser.from(unavailablePresencesReceivedByTwo.get(0)).getItem().getNick(), + "Expected the 'unavailable' presence of user '" + conTwo.getUser() + "' reflecting their nickname change in room '" + mucAddress + "' as received by themselves to include the new nickname (but it did not)."); + + // Validate that the received 'available' presence stanzas have the new nickname as from + assertEquals(nicknameTwoNew, availablePresencesReceivedByOne.get(0).getFrom().getResourceOrEmpty(), "Expected the 'available' presence of '" + conTwo.getUser() + "' as received by '" + conOne.getUser() + "' in room '" + mucAddress + "' to be sent 'from' their new nickname (but it was not)."); + assertEquals(nicknameTwoNew, availablePresencesReceivedByTwo.get(0).getFrom().getResourceOrEmpty(), "Expected the 'available' presence of '" + conTwo.getUser() + "' as received by themselves in room '" + mucAddress + "' to be sent 'from' their new nickname (but it was not)."); + + } finally { + tryDestroy(mucAsSeenByOne); + } + } + + /** + * Asserts that user can not change nickname to one that is already in use. + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "7.6", quote = + "If the user attempts to change his or her room nickname to a room nickname that is already in use by " + + "another user (or that is reserved by another user affiliated with the room, e.g., a member or owner), the " + + "service MUST deny the nickname change request and inform the user of the conflict; this is done by " + + "returning a presence stanza of type \"error\" specifying a error condition:") + public void mucBlockChangeNicknameInformationTest() throws Exception { + EntityBareJid mucAddress = getRandomRoom("smack-inttest-blockchangenickname"); + + MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); + + final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString); + final Resourcepart nicknameTwoOriginal = Resourcepart.from("two-original-" + randomString); + + createMuc(mucAsSeenByOne, nicknameOne); + + SimpleResultSyncPoint participantOneSeesTwoEnter = new SimpleResultSyncPoint(); + mucAsSeenByOne.addParticipantListener(presence -> { + if (nicknameTwoOriginal.equals(presence.getFrom().getResourceOrEmpty())) { + participantOneSeesTwoEnter.signal(); + } + }); + + // Have participant two enter the room + mucAsSeenByTwo.join(nicknameTwoOriginal); + participantOneSeesTwoEnter.waitForResult(timeout); + + try { + // Participant two changes nickname + XMPPException.XMPPErrorException conflictErrorException = assertThrows( + XMPPException.XMPPErrorException.class, () -> mucAsSeenByTwo.changeNickname(nicknameOne), + "Expected an error to be returned when '" + conTwo.getUser() + "' tried to change their nickname in room '" + mucAddress + "' to a nickname that was already in use by another occupant (but no error was returned)."); + assertNotNull(conflictErrorException, "Expected an error to be returned when '" + conTwo.getUser() + "' tried to change their nickname in room '" + mucAddress + "' to a nickname that was already in use by another occupant (but no error was returned)."); + assertNotNull(conflictErrorException.getStanzaError(), "Expected an error to be returned when '" + conTwo.getUser() + "' tried to change their nickname in room '" + mucAddress + "' to a nickname that was already in use by another occupant (but no error was returned)."); + assertEquals(StanzaError.Condition.conflict, conflictErrorException.getStanzaError().getCondition(), + "Unexpected conidtion in the (expected) error to was returned when '" + conTwo.getUser() + "' tried to change their nickname in room '" + mucAddress + "' to a nickname that was already in use by another occupant."); + } finally { + tryDestroy(mucAsSeenByOne); + } + } + + /** + * Asserts that when a user leaves a room, they are themselves included on the list of users notified (self-presence). + * + * @throws Exception when errors occur + */ + @SmackIntegrationTest(section = "7.14", quote = + "The service MUST then send a presence stanzas of type \"unavailable\" from the departing user's occupant " + + "JID to the departing occupant's full JIDs, including a status code of \"110\" to indicate that this " + + "notification is \"self-presence\"") + public void mucLeaveTest() throws Exception { + EntityBareJid mucAddress = getRandomRoom("smack-inttest-leave"); + + MultiUserChat muc = mucManagerOne.getMultiUserChat(mucAddress); + try { + muc.join(Resourcepart.from("nick-one")); + + Presence reflectedLeavePresence = muc.leave(); + + MUCUser mucUser = MUCUser.from(reflectedLeavePresence); + assertNotNull(mucUser, "Expected the reflected 'leave' presence of '" + conOne.getUser() + "' that left room '" + mucAddress + "' to include a valid 'user' child element (but it did not)."); + + assertTrue(mucUser.getStatus().contains(MUCUser.Status.PRESENCE_TO_SELF_110), "Expected the reflected 'leave' presence of '" + conOne.getUser() + "' that left room '" + mucAddress + "' to include status '" + MUCUser.Status.PRESENCE_TO_SELF_110 + "' (but it did not)."); + assertEquals(mucAddress + "/nick-one", reflectedLeavePresence.getFrom().toString(), "Unexpected 'from' attribute value in the reflected 'leave' presence of '" + conOne.getUser() + "' that left room '" + mucAddress + "'."); + assertEquals(conOne.getUser().asEntityFullJidIfPossible().toString(), reflectedLeavePresence.getTo().toString(), "Unexpected 'to' attribute value in the reflected 'leave' presence of '" + conOne.getUser() + "' that left room '" + mucAddress + "'."); + } finally { + muc.join(Resourcepart.from("nick-one")); // We need to be in the room to destroy the room + tryDestroy(muc); + } + } +} diff --git a/smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/util/MultiResultSyncPointTest.java b/smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/util/MultiResultSyncPointTest.java new file mode 100644 index 000000000..5a4db37c4 --- /dev/null +++ b/smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/util/MultiResultSyncPointTest.java @@ -0,0 +1,108 @@ +/** + * + * Copyright 2024 Guus der Kinderen + * + * 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.igniterealtime.smack.inttest.util; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import java.util.List; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.TimeoutException; + +import org.jivesoftware.smack.util.Async; + +import org.junit.jupiter.api.Test; + +public class MultiResultSyncPointTest { + @Test + public void testResultSyncPoint() throws Exception { + final String result1 = "r1"; + final String result2 = "r2"; + final CyclicBarrier barrier = new CyclicBarrier(2); + final MultiResultSyncPoint rsp = new MultiResultSyncPoint<>(2); + Async.go(new Async.ThrowingRunnable() { + @Override + public void runOrThrow() throws InterruptedException, BrokenBarrierException { + barrier.await(); + rsp.signal(result1); + rsp.signal(result2); + } + }); + barrier.await(); + List receivedResult = rsp.waitForResults(60 * 1000); + assertTrue(receivedResult.contains(result1)); + assertTrue(receivedResult.contains(result2)); + } + + @Test + public void exceptionTestResultSyncPoint() throws Exception { + final CyclicBarrier barrier = new CyclicBarrier(2); + final ResultSyncPoint rsp = new ResultSyncPoint<>(); + Async.go(new Async.ThrowingRunnable() { + @Override + public void runOrThrow() throws InterruptedException, BrokenBarrierException { + barrier.await(); + rsp.signal(new MultiResultSyncPointTest.TestException()); + } + }); + barrier.await(); + assertThrows(MultiResultSyncPointTest.TestException.class, () -> rsp.waitForResult(60 * 1000)); + } + + @Test + public void testTimeout() throws Exception { + final MultiResultSyncPoint rsp = new MultiResultSyncPoint<>(2); + try { + rsp.waitForResults(100); + fail("A timeout exception should have been thrown."); + } catch (TimeoutException e) { + // Expected + } + } + + @Test + public void testTimeoutWithOneResult() throws Exception { + final String result1 = "partial"; + final CyclicBarrier barrier = new CyclicBarrier(2); + final MultiResultSyncPoint rsp = new MultiResultSyncPoint<>(2); + Async.go(new Async.ThrowingRunnable() { + @Override + public void runOrThrow() throws InterruptedException, BrokenBarrierException { + barrier.await(); + rsp.signal(result1); + } + }); + barrier.await(); + try { + rsp.waitForResults(100); + fail("A timeout exception should have been thrown."); + } catch (TimeoutException e) { + // Expected + } + } + + private static class TestException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1L; + + } +} diff --git a/smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/util/ResultSyncPointTest.java b/smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/util/ResultSyncPointTest.java index 589880204..c6e22bd72 100644 --- a/smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/util/ResultSyncPointTest.java +++ b/smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/util/ResultSyncPointTest.java @@ -18,9 +18,11 @@ package org.igniterealtime.smack.inttest.util; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.fail; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.TimeoutException; import org.jivesoftware.smack.util.Async; @@ -60,6 +62,17 @@ public class ResultSyncPointTest { assertThrows(TestException.class, () -> rsp.waitForResult(60 * 1000)); } + @Test + public void testTimeout() throws Exception { + final MultiResultSyncPoint rsp = new MultiResultSyncPoint<>(2); + try { + rsp.waitForResults(100); + fail("A timeout exception should have been thrown."); + } catch (TimeoutException e) { + // Expected + } + } + private static class TestException extends Exception { /** From e79934938c4ca4ddc50c68f311f2fe0bf0e74a8b Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Tue, 30 Apr 2024 22:00:51 +0200 Subject: [PATCH 032/150] [sinttest] Add optional version to specification reference Some specifications are versioned. XEPs, for example, typically are. It is useful to annotate an implementation with the specific version of the specification that is being tested. --- .../smack/inttest/SmackIntegrationTestFramework.java | 3 +++ .../inttest/annotations/SpecificationReference.java | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java index 0c9b56d3f..3db80163f 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java @@ -179,6 +179,9 @@ public class SmackIntegrationTestFramework { return null; } String line = spec.document().trim(); + if (!spec.version().isBlank()) { + line += " (version " + spec.version() + ")"; + } final SmackIntegrationTest test = method.getAnnotation(SmackIntegrationTest.class); if (!test.section().isBlank()) { diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/annotations/SpecificationReference.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/annotations/SpecificationReference.java index 947dc3b90..beadb7782 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/annotations/SpecificationReference.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/annotations/SpecificationReference.java @@ -23,7 +23,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * Reference to a specific part of a specification. + * Reference to a specification document. * * @author Guus der Kinderen, guus@goodbytes.nl */ @@ -38,4 +38,11 @@ public @interface SpecificationReference { * @return a document identifier */ String document(); + + /** + * An optional version number, such as '1.2.0'. + * + * @return a version number + */ + String version() default ""; } From e0f335be405b28be240c1483a34e26b07203f370 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 8 May 2024 14:53:31 +0200 Subject: [PATCH 033/150] [smack-repl] Bump Ammonite to 3.0.0-M1 and Scala to 2.13.13 --- smack-repl/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/smack-repl/build.gradle b/smack-repl/build.gradle index 6e098eb52..a7e1017d0 100644 --- a/smack-repl/build.gradle +++ b/smack-repl/build.gradle @@ -9,14 +9,14 @@ apply plugin: 'scala' apply plugin: 'com.github.alisiikh.scalastyle_2.12' ext { - scalaVersion = '2.13.12' + scalaVersion = '2.13.13' } dependencies { api project(':smack-examples') implementation "org.scala-lang:scala-library:$scalaVersion" - implementation "com.lihaoyi:ammonite_$scalaVersion:2.5.11" + implementation "com.lihaoyi:ammonite_$scalaVersion:3.0.0-M1" } scalaStyle { From e08c95a0a1720b5c29d50305ab86cb6cf426aab3 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 8 May 2024 14:53:49 +0200 Subject: [PATCH 034/150] [smack-repl] Fix scala.repl's imports --- smack-repl/scala.repl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/smack-repl/scala.repl b/smack-repl/scala.repl index 1da355d19..0e0dee4db 100644 --- a/smack-repl/scala.repl +++ b/smack-repl/scala.repl @@ -5,4 +5,5 @@ import org.jivesoftware.smack.util.TLSUtils import org.jivesoftware.smack.tcp._ import org.jxmpp.jid.impl.JidCreate -import org.igniterealtime.smack.smackrepl.IoT._ +import org.igniterealtime.smack.examples._ +import org.igniterealtime.smack.examples.IoT._ From 617d1bfff24fd10d0c1fc0c14cbec44881f67268 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 8 May 2024 14:59:34 +0200 Subject: [PATCH 035/150] [smack-examples] Add XmppConnectionTool --- .../smack/examples/XmppConnectionTool.java | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 smack-examples/src/main/java/org/igniterealtime/smack/examples/XmppConnectionTool.java diff --git a/smack-examples/src/main/java/org/igniterealtime/smack/examples/XmppConnectionTool.java b/smack-examples/src/main/java/org/igniterealtime/smack/examples/XmppConnectionTool.java new file mode 100644 index 000000000..c44adb157 --- /dev/null +++ b/smack-examples/src/main/java/org/igniterealtime/smack/examples/XmppConnectionTool.java @@ -0,0 +1,82 @@ +/** + * + * Copyright 2024 Florian Schmaus. + * + * This file is part of smack-examples. + * + * smack-examples is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +package org.igniterealtime.smack.examples; + +import java.io.IOException; + +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.SmackException.NoResponseException; +import org.jivesoftware.smack.SmackException.NotConnectedException; +import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; +import org.jivesoftware.smack.c2s.ModularXmppClientToServerConnection; +import org.jivesoftware.smack.c2s.ModularXmppClientToServerConnectionConfiguration; +import org.jivesoftware.smack.debugger.ConsoleDebugger; +import org.jivesoftware.smack.debugger.SmackDebuggerFactory; +import org.jivesoftware.smackx.omemo.util.OmemoConstants; +import org.jivesoftware.smackx.pep.PepManager; +import org.jivesoftware.smackx.pubsub.PubSubManager; + +import org.jxmpp.stringprep.XmppStringprepException; + +public class XmppConnectionTool { + + public final ModularXmppClientToServerConnection connection; + + public XmppConnectionTool(ModularXmppClientToServerConnection connection) { + this.connection = connection; + } + + public boolean purgeOmemoInformation() + throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { + PepManager pepManager = PepManager.getInstanceFor(connection); + PubSubManager pepPubSubManager = pepManager.getPepPubSubManager(); + + // TODO: Also delete "bundles" nodes. + return pepPubSubManager.deleteNode(OmemoConstants.PEP_NODE_DEVICE_LIST); + } + + public static XmppConnectionTool of(String jid, String password, boolean debug) + throws XMPPException, SmackException, IOException, InterruptedException { + ModularXmppClientToServerConnection connection = createConnectionFor(jid, password, debug); + connection.connect().login(); + return new XmppConnectionTool(connection); + } + + public static ModularXmppClientToServerConnection createConnectionFor(String jid, String password, boolean debug) + throws XmppStringprepException { + + final SmackDebuggerFactory smackDebuggerFactory; + if (debug) { + smackDebuggerFactory = ConsoleDebugger.Factory.INSTANCE; + } else { + smackDebuggerFactory = null; + } + + ModularXmppClientToServerConnectionConfiguration.Builder configurationBuilder = ModularXmppClientToServerConnectionConfiguration + .builder().setXmppAddressAndPassword(jid, password).setDebuggerFactory(smackDebuggerFactory); + + ModularXmppClientToServerConnectionConfiguration configuration = configurationBuilder.build(); + + ModularXmppClientToServerConnection connection = new ModularXmppClientToServerConnection(configuration); + return connection; + } +} From 4cc9a7d7ebdcdf48ccf19deef82256dd39cbcbb5 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Fri, 10 May 2024 15:01:44 +0200 Subject: [PATCH 036/150] [sinttest] Configuration.normalizeSpecification() should be public It is likely to be desirable to re-use the normalization of specification references, for example in implementations of `TestRunResultProcessor`. --- .../java/org/igniterealtime/smack/inttest/Configuration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java index a60b3e21e..dfcd74130 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java @@ -769,7 +769,7 @@ public final class Configuration { return disabledSpecifications.contains(normalizeSpecification(specification)); } - static String normalizeSpecification(String specification) { + public static String normalizeSpecification(String specification) { if (specification == null || specification.isBlank()) { return null; } From 121d4ac2459dd6244d36a90794a2779ba7a57aad Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Fri, 10 May 2024 14:45:31 +0200 Subject: [PATCH 037/150] [sinttest] Normalization of SpecificationReference to include dash-seperator When comparing SINT-configuration to annotations, a bit of normalization occurs, to ensure that common variations in denoting a specification are detected to be equal to each-other. The dash (`-`) character is commonly used when referencing a specification (eg: `XEP-0001`). This commit ensures that usage of a dash (`-`) character is included in the normalization process, making `XEP 0001`, `XEP0001` and `XEP-0001` all to be identified as the same reference. --- .../smack/inttest/Configuration.java | 2 +- .../smack/inttest/ConfigurationTest.java | 98 +++++++++++++++++++ 2 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/ConfigurationTest.java diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java index a60b3e21e..323429ad3 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java @@ -773,6 +773,6 @@ public final class Configuration { if (specification == null || specification.isBlank()) { return null; } - return specification.replaceAll("\\s", "").toUpperCase(); + return specification.replaceAll("[\\s-]", "").toUpperCase(); } } diff --git a/smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/ConfigurationTest.java b/smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/ConfigurationTest.java new file mode 100644 index 000000000..727b8a756 --- /dev/null +++ b/smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/ConfigurationTest.java @@ -0,0 +1,98 @@ +/** + * + * Copyright 2024 Guus der Kinderen + * + * 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.igniterealtime.smack.inttest; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +/** + * Verifies the functionality that's implemented in {@link Configuration}. + */ +public class ConfigurationTest { + @Test + public void testNormalizeXepUpperCaseNoSeperator() { + // Setup test fixture. + final String input = "XEP0001"; + + // Execute system under test. + final String output = Configuration.normalizeSpecification(input); + + // Verify results. + assertEquals("XEP0001", output); + } + + @Test + public void testNormalizeXepLowerCaseNoSeperator() { + // Setup test fixture. + final String input = "xep0001"; + + // Execute system under test. + final String output = Configuration.normalizeSpecification(input); + + // Verify results. + assertEquals("XEP0001", output); + } + + @Test + public void testNormalizeXepUpperCaseDash() { + // Setup test fixture. + final String input = "XEP-0001"; + + // Execute system under test. + final String output = Configuration.normalizeSpecification(input); + + // Verify results. + assertEquals("XEP0001", output); + } + + @Test + public void testNormalizeXepLowerCaseDash() { + // Setup test fixture. + final String input = "xep-0001"; + + // Execute system under test. + final String output = Configuration.normalizeSpecification(input); + + // Verify results. + assertEquals("XEP0001", output); + } + + @Test + public void testNormalizeXepUpperCaseSpace() { + // Setup test fixture. + final String input = "XEP 0001"; + + // Execute system under test. + final String output = Configuration.normalizeSpecification(input); + + // Verify results. + assertEquals("XEP0001", output); + } + + @Test + public void testNormalizeXepLowerCaseSpace() { + // Setup test fixture. + final String input = "xep 0001"; + + // Execute system under test. + final String output = Configuration.normalizeSpecification(input); + + // Verify results. + assertEquals("XEP0001", output); + } +} From 1bf0aed0f525acc9a3910cb96a3b7dd9e0fa8162 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 20 May 2024 15:09:22 +0200 Subject: [PATCH 038/150] [build.gradle] Add junit-platform-launcher add testRuntimeOnly Fixes NoSuchMethodError: 'java.util.Set org.junit.platform.engine.TestDescriptor.getAncestors() when running unit tests in Eclipse. --- build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle b/build.gradle index be40f20fe..1bf116655 100644 --- a/build.gradle +++ b/build.gradle @@ -313,6 +313,8 @@ tasks.withType(Javadoc) { testFixturesApi "org.junit.jupiter:junit-jupiter-api:$junitVersion" testImplementation "org.junit.jupiter:junit-jupiter-params:$junitVersion" testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junitVersion" + // https://stackoverflow.com/a/77274251/194894 + testRuntimeOnly "org.junit.platform:junit-platform-launcher" // The smack-extensions subproject uses mockito in its fest // fixtures, and we want to have mockito also available in From c4ce6b470795b764e8a2bcaf562ac8e9a2129bf2 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 20 May 2024 15:10:56 +0200 Subject: [PATCH 039/150] [muc] Add support for muc#roomconfig_roomname in MucConfigFormManager --- .../smackx/muc/MucConfigFormManager.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java index 80371f7c8..7eff69fa0 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java @@ -1,6 +1,6 @@ /** * - * Copyright 2015-2020 Florian Schmaus + * Copyright 2015-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -88,6 +88,10 @@ public class MucConfigFormManager { */ public static final String MUC_ROOMCONFIG_PUBLICLYSEARCHABLEROOM = "muc#roomconfig_publicroom"; + /** + * The constant String {@value}. + */ + public static final String MUC_ROOMCONFIG_ROOMNAME = "muc#roomconfig_roomname"; private final MultiUserChat multiUserChat; private final FillableForm answerForm; @@ -267,6 +271,18 @@ public class MucConfigFormManager { return this; } + public boolean supportsRoomname() { + return answerForm.hasField(MUC_ROOMCONFIG_ROOMNAME); + } + + public MucConfigFormManager setRoomName(String roomName) throws MucConfigurationNotSupportedException { + if (!supportsRoomname()) { + throw new MucConfigurationNotSupportedException(MUC_ROOMCONFIG_ROOMNAME); + } + answerForm.setAnswer(MUC_ROOMCONFIG_ROOMNAME, roomName); + return this; + } + /** * Check if the room supports password protection. * From e70d0cd858afbc4b558b85426f81b58d59b1de4d Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 20 May 2024 15:11:28 +0200 Subject: [PATCH 040/150] [sinttest] Improve MultiUResultSyncPoint's TimoutException message --- .../igniterealtime/smack/inttest/util/MultiResultSyncPoint.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/MultiResultSyncPoint.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/MultiResultSyncPoint.java index 22e046d64..d04de77c1 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/MultiResultSyncPoint.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/MultiResultSyncPoint.java @@ -40,7 +40,7 @@ public class MultiResultSyncPoint { wait(deadline - now); now = System.currentTimeMillis(); } - if (now >= deadline) throw new TimeoutException("Timeout waiting " + timeout + " millis"); + if (now >= deadline) throw new TimeoutException("MultiResultSyncPoint timeout waiting " + timeout + " millis. Got " + results.size() + " results of " + expectedResultCount + " results"); if (exception != null) throw exception; return new ArrayList<>(results); } From 1836537c42966f50d45fdf22e184e875e6cc8e84 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 20 May 2024 15:12:11 +0200 Subject: [PATCH 041/150] [core] Add unit test for IQ parsing Motivated by https://discourse.igniterealtime.org/t/question-about-tigase-server-8-3-1-and-smack-4-4-7/93796/ --- .../org/jivesoftware/smack/packet/IqTest.java | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/smack-core/src/test/java/org/jivesoftware/smack/packet/IqTest.java b/smack-core/src/test/java/org/jivesoftware/smack/packet/IqTest.java index b8f192bd7..041c66981 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/packet/IqTest.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/packet/IqTest.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2023 Florian Schmaus + * Copyright © 2023-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,13 @@ package org.jivesoftware.smack.packet; import static org.jivesoftware.smack.test.util.XmlAssertUtil.assertXmlSimilar; +import org.jivesoftware.smack.test.util.SmackTestUtil; +import org.jivesoftware.smack.util.PacketParserUtils; +import org.jivesoftware.smack.xml.XmlPullParser; + import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; public class IqTest { @@ -35,4 +41,21 @@ public class IqTest { assertXmlSimilar(expected, errorIq.toXML()); } + @ParameterizedTest + @EnumSource(SmackTestUtil.XmlPullParserKind.class) + public void testIqWithXmlns(SmackTestUtil.XmlPullParserKind parserKind) throws Exception { + final String iqXml = "" + + "" + + "foo@tigase.mydomain.org/myresource" + + "" + + ""; + final String xml = + "" + + iqXml + + ""; + + XmlPullParser parser = SmackTestUtil.getParserFor(xml, "iq", parserKind); + IQ iq = PacketParserUtils.parseIQ(parser); + assertXmlSimilar(iqXml, iq.toXML()); + } } From c34c9bdb62978d56ded495692c88bbd07f0750bd Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 20 May 2024 21:38:18 +0200 Subject: [PATCH 042/150] [muc] Fix MultiUserChat.changeNickname(Resourcepart) Using this method used to result in a deadlock, as shown by these two threads "main" #1 prio=5 os_prio=0 cpu=926.39ms elapsed=21.00s tid=0x00007f463802c800 nid=0x5a691 in Object.wait() [0x00007f463f323000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(java.base@11.0.23/Native Method) - waiting on <0x0000000622e82fd8> (a org.jivesoftware.smack.StanzaCollector) at org.jivesoftware.smack.StanzaCollector.nextResult(StanzaCollector.java:206) - waiting to re-lock in wait() <0x0000000622e82fd8> (a org.jivesoftware.smack.StanzaCollector) at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:270) at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:228) at org.jivesoftware.smackx.muc.MultiUserChat.changeNickname(MultiUserChat.java:1314) - locked <0x0000000622e19700> (a org.jivesoftware.smackx.muc.MultiUserChat) at org.jivesoftware.smackx.muc.MultiUserChatOccupantIntegrationTest.mucChangeNicknameInformationTest(MultiUserChatOccupantIntegrationTest.java:981) at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(java.base@11.0.23/Native Method) at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(java.base@11.0.23/NativeMethodAccessorImpl.java:62) at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@11.0.23/DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(java.base@11.0.23/Method.java:566) at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework.lambda$runTests$0(SmackIntegrationTestFramework.java:476) at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework$$Lambda$141/0x000000084026e040.execute(Unknown Source) at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework.runConcreteTest(SmackIntegrationTestFramework.java:551) at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework$PreparedTest.run(SmackIntegrationTestFramework.java:759) at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework.runTests(SmackIntegrationTestFramework.java:539) at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework.run(SmackIntegrationTestFramework.java:277) - locked <0x000000062d191318> (a org.igniterealtime.smack.inttest.SmackIntegrationTestFramework) at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework.main(SmackIntegrationTestFramework.java:115) "Smack Cached Executor" #19 daemon prio=5 os_prio=0 cpu=7.85ms elapsed=20.48s tid=0x00007f4638a42800 nid=0x5a6b2 waiting for monitor entry [0x00007f46023fe000] java.lang.Thread.State: BLOCKED (on object monitor) at org.jivesoftware.smackx.muc.MultiUserChat.userHasLeft(MultiUserChat.java:2281) - waiting to lock <0x0000000622e19700> (a org.jivesoftware.smackx.muc.MultiUserChat) at org.jivesoftware.smackx.muc.MultiUserChat.access$800(MultiUserChat.java:117) at org.jivesoftware.smackx.muc.MultiUserChat$3.processStanza(MultiUserChat.java:263) at org.jivesoftware.smack.AbstractXMPPConnection.lambda$invokeStanzaCollectorsAndNotifyRecvListeners$8(AbstractXMPPConnection.java:1654) at org.jivesoftware.smack.AbstractXMPPConnection$$Lambda$127/0x000000084022f440.run(Unknown Source) at org.jivesoftware.smack.AbstractXMPPConnection$10.run(AbstractXMPPConnection.java:2213) at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@11.0.23/ThreadPoolExecutor.java:1128) at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@11.0.23/ThreadPoolExecutor.java:628) at java.lang.Thread.run(java.base@11.0.23/Thread.java:829) The changeNickname() method was synchronized and is userHasLeft(), this caused a deadlock since changeNickname() awaits the presence that is send as result of the nickname change. But this presence is also processed in a listener which invokes userHasLeft(). However, this invocation blocks as userHasLeft() is waiting on the montior currently hold by the thread invoking changeNickname(). To fix this, we change changeNickname() to not take the MultiUserChat monitor, but instead use a dedicate lock. Fixes SMACK-942. --- .../smackx/muc/MultiUserChat.java | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java index b7fd3ad97..999a7d306 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java @@ -1,6 +1,6 @@ /** * - * Copyright 2003-2007 Jive Software. 2020-2022 Florian Schmaus + * Copyright 2003-2007 Jive Software. 2020-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1273,6 +1273,8 @@ public class MultiUserChat { return myRoomJid; } + private static final Object changeNicknameLock = new Object(); + /** * Changes the occupant's nickname to a new nickname within the room. Each room occupant * will receive two presence packets. One of type "unavailable" for the old nickname and one @@ -1287,7 +1289,7 @@ public class MultiUserChat { * @throws InterruptedException if the calling thread was interrupted. * @throws MucNotJoinedException if not joined to the Multi-User Chat. */ - public synchronized void changeNickname(Resourcepart nickname) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException, MucNotJoinedException { + public void changeNickname(Resourcepart nickname) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException, MucNotJoinedException { Objects.requireNonNull(nickname, "Nickname must not be null or blank."); // Check that we already have joined the room before attempting to change the // nickname. @@ -1303,18 +1305,20 @@ public class MultiUserChat { .ofType(Presence.Type.available) .build(); - // Wait for a presence packet back from the server. - StanzaFilter responseFilter = - new AndFilter( - FromMatchesFilter.createFull(jid), - new StanzaTypeFilter(Presence.class)); - StanzaCollector response = connection.createStanzaCollectorAndSend(responseFilter, joinPresence); - // Wait up to a certain number of seconds for a reply. If there is a negative reply, an - // exception will be thrown - response.nextResultOrThrow(); + synchronized (changeNicknameLock) { + // Wait for a presence packet back from the server. + StanzaFilter responseFilter = + new AndFilter( + FromMatchesFilter.createFull(jid), + new StanzaTypeFilter(Presence.class)); + StanzaCollector response = connection.createStanzaCollectorAndSend(responseFilter, joinPresence); + // Wait up to a certain number of seconds for a reply. If there is a negative reply, an + // exception will be thrown + response.nextResultOrThrow(); - // TODO: Shouldn't this handle nickname rewriting by the MUC service? - setNickname(nickname); + // TODO: Shouldn't this handle nickname rewriting by the MUC service? + setNickname(nickname); + } } /** From 9447030cd4d3c0ac72da1279ef4a9e35e9efb594 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 20 May 2024 21:45:47 +0200 Subject: [PATCH 043/150] [muc] Do not invoke userHasLeft() on nickname change When the incoming unavailable presence is signalling a nickname change (303), then do not invoke userHasLeft(), because the user actually does not leave but instead just changes its nickname. Note that this would also have had fixed SMACK-942, as it would resolve the deadlock. However, using a dedicated lock for changeNickname() still seems sensible, and if its just to avoid a bit of lock contention. What this also fixes is that a MultiUserChat does no longer invoke its listener-based callbacks after a nickname change, as previously, after a nickname change, the userHasLeft() would have been invoked, which tears down the listeners. This issue was found with MultiUserChatOccupantIntegrationTest.mucChangeNicknameInformationTest(). --- .../java/org/jivesoftware/smackx/muc/MultiUserChat.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java index 999a7d306..5c3f687c4 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java @@ -258,13 +258,14 @@ public class MultiUserChat { break; case unavailable: occupantsMap.remove(from); - if (mucUser != null && mucUser.hasStatus()) { - if (isUserStatusModification) { + Set status = mucUser.getStatus(); + if (mucUser != null && !status.isEmpty()) { + if (isUserStatusModification && !status.contains(MUCUser.Status.NEW_NICKNAME_303)) { userHasLeft(); } // Fire events according to the received presence code checkPresenceCode( - mucUser.getStatus(), + status, isUserStatusModification, mucUser, from); From c87bb8aaa495928d51eb4c6fcc4ca03f42bd8c65 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 20 May 2024 21:52:01 +0200 Subject: [PATCH 044/150] [sinttest] Ensure that message has body in mucJoinEventOrderingTest() It is possible that messages do not have a body. Therefore, we need to ensure that the message has one before we compare the body. --- .../smackx/muc/MultiUserChatOccupantIntegrationTest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java index 1125e320d..077f863c2 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java @@ -86,7 +86,10 @@ public class MultiUserChatOccupantIntegrationTest extends AbstractMultiUserChatI // Send and wait for the message to have been reflected, so that we can be sure it's part of the MUC history. final SimpleResultSyncPoint messageReflectionSyncPoint = new SimpleResultSyncPoint(); mucAsSeenByOne.addMessageListener(message -> { - if (message.getBody().equals(mucMessage)) { + String body = message.getBody(); + if (body == null) return; + + if (body.equals(mucMessage)) { messageReflectionSyncPoint.signal(); } }); From eed707f39dd7a676476a3edf91619e965c235ed7 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 20 May 2024 21:58:16 +0200 Subject: [PATCH 045/150] [sinttest] Inline createLockedMuc() This method only had one call site and using such "helper" methods has the drawback that it is not immediatly obvious what it does when reading the integration test code. Therefore, we better inline it. --- .../muc/AbstractMultiUserChatIntegrationTest.java | 13 +------------ .../muc/MultiUserChatOccupantIntegrationTest.java | 4 +++- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/AbstractMultiUserChatIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/AbstractMultiUserChatIntegrationTest.java index 2ad9ca2d4..c48cbcf1b 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/AbstractMultiUserChatIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/AbstractMultiUserChatIntegrationTest.java @@ -1,6 +1,6 @@ /** * - * Copyright 2021-2023 Florian Schmaus + * Copyright 2021-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -189,17 +189,6 @@ public abstract class AbstractMultiUserChatIntegrationTest extends AbstractSmack muc.sendConfigurationForm(answerForm); } - static void createLockedMuc(MultiUserChat muc, Resourcepart resourceName) throws - SmackException.NoResponseException, XMPPException.XMPPErrorException, - InterruptedException, MultiUserChatException.MucAlreadyJoinedException, - SmackException.NotConnectedException, - MultiUserChatException.MissingMucCreationAcknowledgeException, - MultiUserChatException.NotAMucServiceException { - muc.create(resourceName); - // Note the absence of handle.makeInstant() here. The room is still being created at this point, until a - // configuration is set. - } - static void setMaxUsers(MultiUserChat muc, int maxUsers) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, InterruptedException, SmackException.NotConnectedException { Form configForm = muc.getConfigurationForm(); FillableForm answerForm = configForm.getFillableForm(); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java index 077f863c2..3ceac42ac 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java @@ -876,7 +876,9 @@ public class MultiUserChatOccupantIntegrationTest extends AbstractMultiUserChatI final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString); final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); - createLockedMuc(mucAsSeenByOne, nicknameOne); + // Note the absence of handle.makeInstant() here. The room is still being created at this point, until a + // configuration is set. + mucAsSeenByOne.create(nicknameOne); try { XMPPException.XMPPErrorException conflictErrorException = assertThrows( From e69e7d23420d96a935da4a0809201216a51de0b3 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 20 May 2024 21:59:32 +0200 Subject: [PATCH 046/150] [sinttest] Add TestNotPossibleException(Throwable) --- .../smack/inttest/TestNotPossibleException.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/TestNotPossibleException.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/TestNotPossibleException.java index 843726ca8..4c09e0f47 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/TestNotPossibleException.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/TestNotPossibleException.java @@ -1,6 +1,6 @@ /** * - * Copyright 2015 Florian Schmaus + * Copyright 2015-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,4 +26,8 @@ public class TestNotPossibleException extends Exception { public TestNotPossibleException(String reason) { super(reason); } + + public TestNotPossibleException(Throwable reason) { + super(reason); + } } From 6cda9a637961bb3bbf472b72142a303dee028b7c Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 20 May 2024 22:00:56 +0200 Subject: [PATCH 047/150] [sinttest] Add ejabberd specific behavior for mucMaxUsersLimitJoinRoomTest ejabberd returns resource-constraint instead of service-unavailable if the maximum number of participants is reached. --- .../MultiUserChatOccupantIntegrationTest.java | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java index 3ceac42ac..5f19e7385 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java @@ -728,18 +728,23 @@ public class MultiUserChatOccupantIntegrationTest extends AbstractMultiUserChatI // it can kick user 2. Both strategies would comply with the specification. So the only thing we can // reasonably test here is whether the room doesn't have more occupants than its max size. - try { - mucAsSeenByThree.join(nicknameThree); - } catch (XMPPException.XMPPErrorException unavailableErrorException) { - // This exception is expected if the muc implementation employs the strategy to deny access beyond the - // maxusers value - if (unavailableErrorException.getStanzaError() == null - || !StanzaError.Condition.service_unavailable.equals( - unavailableErrorException.getStanzaError().getCondition())) { - throw unavailableErrorException; - } + XMPPException.XMPPErrorException errorException = assertThrows(XMPPException.XMPPErrorException.class, () -> mucAsSeenByThree.join(nicknameThree)); + + final StanzaError.Condition expectedCondition; + switch (sinttestConfiguration.compatibilityMode) { + default: + expectedCondition = StanzaError.Condition.service_unavailable; + break; + case ejabberd: + expectedCondition = StanzaError.Condition.resource_constraint; + break; } + StanzaError stanzaError = errorException.getStanzaError(); + assertNotNull(stanzaError); + + assertEquals(expectedCondition, stanzaError.getCondition()); + // Now we should wait until participant one is informed about the (probably failed) new participant three // room join. But if joining failed, there will be no such update. All we can reasonably do is wait until // participant three has received its own presence response. This is not watertight though. From 90c7dc4390705884eee987095d656c251b018a50 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 20 May 2024 22:02:10 +0200 Subject: [PATCH 048/150] [sinttest] Add ejabberd specific behavior for mucJoinLockedRoomTest() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ejabberd does not seem to implement the MUC locked behavior specified in XEP-0045 § 7.2.10. --- .../smackx/muc/MultiUserChatOccupantIntegrationTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java index 5f19e7385..484cfae73 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java @@ -40,6 +40,7 @@ import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smackx.muc.packet.MUCItem; import org.jivesoftware.smackx.muc.packet.MUCUser; +import org.igniterealtime.smack.inttest.Configuration; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; @@ -873,6 +874,10 @@ public class MultiUserChatOccupantIntegrationTest extends AbstractMultiUserChatI "initial configuration and therefore before the room officially exists), the service MUST refuse entry and " + "return an error to the user.") public void mucJoinLockedRoomTest() throws Exception { + if (sinttestConfiguration.compatibilityMode == Configuration.CompatibilityMode.ejabberd) { + throw new TestNotPossibleException("ejabberd does not implement MUC locked rooms as per XEP-0045 § 7.2.10"); + } + EntityBareJid mucAddress = getRandomRoom("smack-inttest-lockedroom"); MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); From 1d498efd46308f5957f688fcd958fb812101c618 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 20 May 2024 22:05:17 +0200 Subject: [PATCH 049/150] [muc] Add support for muc#roomconfig_enablelogging to MucConfigFormManager --- .../smackx/muc/MucConfigFormManager.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java index 7eff69fa0..9f2778e9c 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java @@ -93,6 +93,11 @@ public class MucConfigFormManager { */ public static final String MUC_ROOMCONFIG_ROOMNAME = "muc#roomconfig_roomname"; + /** + * The constant String {@value}. + */ + public static final String MUC_ROOMCONFIG_ENABLE_PUBLIC_LOGGING = "muc#roomconfig_enablelogging"; + private final MultiUserChat multiUserChat; private final FillableForm answerForm; private final List owners; @@ -331,6 +336,26 @@ public class MucConfigFormManager { return this; } + public boolean supportsPublicLogging() { + return answerForm.hasField(MUC_ROOMCONFIG_ENABLE_PUBLIC_LOGGING); + } + + public MucConfigFormManager setPublicLogging(boolean enabled) throws MucConfigurationNotSupportedException { + if (!supportsPublicLogging()) { + throw new MucConfigurationNotSupportedException(MUC_ROOMCONFIG_ENABLE_PUBLIC_LOGGING); + } + answerForm.setAnswer(MUC_ROOMCONFIG_ENABLE_PUBLIC_LOGGING, enabled); + return this; + } + + public MucConfigFormManager enablePublicLogging() throws MucConfigurationNotSupportedException { + return setPublicLogging(true); + } + + public MucConfigFormManager disablPublicLogging() throws MucConfigurationNotSupportedException { + return setPublicLogging(false); + } + /** * Set the room secret, aka the room password. If set and enabled, the password is required to * join the room. Note that this does only set it by does not enable password protection. Use From 482a117e0da416110319192630b85dfc6c0fc533 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 20 May 2024 22:05:52 +0200 Subject: [PATCH 050/150] [sinttest] Migrate mucJoinRoomWithPublicLoggingTest() to use MucConfigFormManager This also ensures that the test does not fail if the service does not support the required MUC configuration option. --- .../smackx/muc/AbstractMultiUserChatIntegrationTest.java | 6 ------ .../smackx/muc/MultiUserChatOccupantIntegrationTest.java | 8 +++++++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/AbstractMultiUserChatIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/AbstractMultiUserChatIntegrationTest.java index c48cbcf1b..0f803e97f 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/AbstractMultiUserChatIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/AbstractMultiUserChatIntegrationTest.java @@ -196,10 +196,4 @@ public abstract class AbstractMultiUserChatIntegrationTest extends AbstractSmack muc.sendConfigurationForm(answerForm); } - static void setPublicLogging(MultiUserChat muc, boolean publicLogging) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, InterruptedException, SmackException.NotConnectedException { - Form configForm = muc.getConfigurationForm(); - FillableForm answerForm = configForm.getFillableForm(); - answerForm.setAnswer("muc#roomconfig_enablelogging", publicLogging); - muc.sendConfigurationForm(answerForm); - } } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java index 484cfae73..0701ecede 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java @@ -37,6 +37,7 @@ import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.packet.StanzaError; import org.jivesoftware.smack.sm.predicates.ForEveryMessage; import org.jivesoftware.smack.util.StringUtils; +import org.jivesoftware.smackx.muc.MultiUserChatException.MucConfigurationNotSupportedException; import org.jivesoftware.smackx.muc.packet.MUCItem; import org.jivesoftware.smackx.muc.packet.MUCUser; @@ -924,12 +925,17 @@ public class MultiUserChatOccupantIntegrationTest extends AbstractMultiUserChatI final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); createMuc(mucAsSeenByOne, nicknameOne); - setPublicLogging(mucAsSeenByOne, true); try { + mucAsSeenByOne.getConfigFormManager() + .enablePublicLogging() + .submitConfigurationForm(); + Presence twoPresence = mucAsSeenByTwo.join(nicknameTwo); assertTrue(MUCUser.from(twoPresence).getStatus().stream().anyMatch(status -> 170 == status.getCode()), "Expected initial presence reflected to '" + conTwo.getUser() + "' when joining room '" + mucAddress + "' to include the status code '170' (but it did not)."); + } catch (MucConfigurationNotSupportedException e) { + throw new TestNotPossibleException(e); } finally { mucAsSeenByOne.destroy(); } From 2a243fe3b6486353d8f96183228433cd7692e86a Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 20 May 2024 22:06:56 +0200 Subject: [PATCH 051/150] [sinttest] Do not use Java stream() API to check if MUC status is set MUCUser.getStatus() returns a set, checking if a particular MUC status number is set should be done via a simple and efficient set operation and not by resorting to using Java's stream API. --- .../smackx/muc/MultiUserChatOccupantIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java index 0701ecede..323a245a6 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java @@ -932,7 +932,7 @@ public class MultiUserChatOccupantIntegrationTest extends AbstractMultiUserChatI .submitConfigurationForm(); Presence twoPresence = mucAsSeenByTwo.join(nicknameTwo); - assertTrue(MUCUser.from(twoPresence).getStatus().stream().anyMatch(status -> 170 == status.getCode()), + assertTrue(MUCUser.from(twoPresence).getStatus().contains(MUCUser.Status.create(170)), "Expected initial presence reflected to '" + conTwo.getUser() + "' when joining room '" + mucAddress + "' to include the status code '170' (but it did not)."); } catch (MucConfigurationNotSupportedException e) { throw new TestNotPossibleException(e); From 9f58c992bdd462fdd66965e39cf0d157a4e8fdd9 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 20 May 2024 22:10:58 +0200 Subject: [PATCH 052/150] [sinttest] Improve mucChangeNicknameInformationTest() Only declare the body of the participant listeners once. And increase the try block, to account, for example, for participantOneSeesTwoEnter.waitForResult() throwing. --- .../MultiUserChatOccupantIntegrationTest.java | 57 +++++++++---------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java index 323a245a6..437b552bd 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java @@ -1,6 +1,6 @@ /** * - * Copyright 2015-2020 Florian Schmaus, 2021 Dan Caseley + * Copyright 2015-2024 Florian Schmaus, 2021 Dan Caseley * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,7 @@ import java.util.Set; import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; +import org.jivesoftware.smack.PresenceListener; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.Message; @@ -968,36 +969,32 @@ public class MultiUserChatOccupantIntegrationTest extends AbstractMultiUserChatI createMuc(mucAsSeenByOne, nicknameOne); - SimpleResultSyncPoint participantOneSeesTwoEnter = new SimpleResultSyncPoint(); - mucAsSeenByOne.addParticipantListener(presence -> { - if (nicknameTwoOriginal.equals(presence.getFrom().getResourceOrEmpty())) { - participantOneSeesTwoEnter.signal(); - } - }); - - // Have participant two enter the room - mucAsSeenByTwo.join(nicknameTwoOriginal); - participantOneSeesTwoEnter.waitForResult(timeout); - - // Although logic dictates that the 'unavailable' presence stanzas for the old nick should precede the presence - // stanza for the new nick - the specification does not dictate that. So we should allow for the order to be - // reversed. Here we will expect an unavailable and an available presence stanza sent to both participant one - // and participant two. So that adds up to a total of four. - MultiResultSyncPoint participantTwoPresencesSyncPoint = new MultiResultSyncPoint<>(4); - mucAsSeenByOne.addParticipantListener(presence -> { - if (nicknameTwoOriginal.equals(presence.getFrom().getResourceOrEmpty()) || nicknameTwoNew.equals( - presence.getFrom().getResourceOrEmpty())) { - participantTwoPresencesSyncPoint.signal(presence); - } - }); - mucAsSeenByTwo.addParticipantListener(presence -> { - if (nicknameTwoOriginal.equals(presence.getFrom().getResourceOrEmpty()) || nicknameTwoNew.equals( - presence.getFrom().getResourceOrEmpty())) { - participantTwoPresencesSyncPoint.signal(presence); - } - }); - try { + SimpleResultSyncPoint participantOneSeesTwoEnter = new SimpleResultSyncPoint(); + mucAsSeenByOne.addParticipantListener(presence -> { + if (nicknameTwoOriginal.equals(presence.getFrom().getResourceOrEmpty())) { + participantOneSeesTwoEnter.signal(); + } + }); + + // Have participant two enter the room + mucAsSeenByTwo.join(nicknameTwoOriginal); + participantOneSeesTwoEnter.waitForResult(timeout); + + // Although logic dictates that the 'unavailable' presence stanzas for the old nick should precede the presence + // stanza for the new nick - the specification does not dictate that. So we should allow for the order to be + // reversed. Here we will expect an unavailable and an available presence stanza sent to both participant one + // and participant two. So that adds up to a total of four. + MultiResultSyncPoint participantTwoPresencesSyncPoint = new MultiResultSyncPoint<>(4); + PresenceListener mucPresenceListener = presence -> { + Resourcepart fromResource = presence.getFrom().getResourceOrEmpty(); + if (nicknameTwoOriginal.equals(fromResource) || nicknameTwoNew.equals(fromResource)) { + participantTwoPresencesSyncPoint.signal(presence); + } + }; + mucAsSeenByOne.addParticipantListener(mucPresenceListener); + mucAsSeenByTwo.addParticipantListener(mucPresenceListener); + // Participant two changes nickname mucAsSeenByTwo.changeNickname(nicknameTwoNew); final List partTwoPresencesReceived = participantTwoPresencesSyncPoint.waitForResults( From c5e3f89e215e5e7b310e7b1ecd6d7b671afebce9 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 20 May 2024 22:17:04 +0200 Subject: [PATCH 053/150] [sinttest] Add MultiUserChatIntegrationTest.mucNameChangeTest() --- .../muc/MultiUserChatIntegrationTest.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java index 421109a00..e2fd308a8 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java @@ -23,8 +23,15 @@ import java.util.concurrent.TimeoutException; import org.jivesoftware.smack.MessageListener; import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.SmackException.NoResponseException; +import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smackx.muc.MultiUserChatException.MissingMucCreationAcknowledgeException; +import org.jivesoftware.smackx.muc.MultiUserChatException.MucAlreadyJoinedException; +import org.jivesoftware.smackx.muc.MultiUserChatException.MucConfigurationNotSupportedException; +import org.jivesoftware.smackx.muc.MultiUserChatException.NotAMucServiceException; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.TestNotPossibleException; @@ -33,6 +40,7 @@ import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.parts.Resourcepart; +import org.jxmpp.stringprep.XmppStringprepException; @SpecificationReference(document = "XEP-0045") public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrationTest { @@ -119,4 +127,29 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati assertEquals(0, muc.getOccupantsCount(), "Expected room " + mucAddress + " to no longer have any occupants after it was destroyed (but it has)."); assertNull(muc.getNickname()); } + + @SmackIntegrationTest + public void mucNameChangeTest() + throws XmppStringprepException, MucAlreadyJoinedException, MissingMucCreationAcknowledgeException, + NotAMucServiceException, NoResponseException, XMPPErrorException, NotConnectedException, + InterruptedException, MucConfigurationNotSupportedException { + EntityBareJid mucAddress = getRandomRoom("smack-inttest-muc-name-change"); + + MultiUserChat muc = mucManagerOne.getMultiUserChat(mucAddress); + createMuc(muc, Resourcepart.from("one-" + randomString)); + + final String newRoomName = "New Room Name (" + randomString + ")"; + + try { + muc.getConfigFormManager() + .setRoomName(newRoomName) + .submitConfigurationForm(); + + MultiUserChatManager mucManager = MultiUserChatManager.getInstanceFor(conTwo); + RoomInfo roomInfo = mucManager.getRoomInfo(muc.getRoom()); + assertEquals(newRoomName, roomInfo.getName()); + } finally { + tryDestroy(muc); + } + } } From 35f621be053eced19555aedcb246e567eecd5efc Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 20 May 2024 23:08:23 +0200 Subject: [PATCH 054/150] [muc] Switch away from deprecated DefaultUserStatusListener in mucDestroyTest() --- .../jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java index e2fd308a8..cc92fbac9 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java @@ -101,8 +101,7 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati final SimpleResultSyncPoint mucDestroyed = new SimpleResultSyncPoint(); - @SuppressWarnings("deprecation") - DefaultUserStatusListener userStatusListener = new DefaultUserStatusListener() { + UserStatusListener userStatusListener = new UserStatusListener() { @Override public void roomDestroyed(MultiUserChat alternateMUC, String reason) { mucDestroyed.signal(); From bf6b7bd692adaf522ecbacf0ee4bb4f3d4e95633 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 20 May 2024 23:08:53 +0200 Subject: [PATCH 055/150] [sinttest] Use set operation instead of Java stream API in mucDestroyTest() --- .../jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java index cc92fbac9..ec18b6c56 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java @@ -111,7 +111,7 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati muc.addUserStatusListener(userStatusListener); // These would be a test implementation bug, not assertion failure. - if (mucManagerOne.getJoinedRooms().stream().noneMatch(room -> room.equals(mucAddress))) { + if (!mucManagerOne.getJoinedRooms().contains(mucAddress)) { throw new IllegalStateException("Expected user to have joined a room '" + mucAddress + "' (but does not appear to have done so)."); } From d2810cf9b6c9f91d57269040a65c133eeebbbe07 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 20 May 2024 23:09:45 +0200 Subject: [PATCH 056/150] [sinttest] Move throw statement before setting the listener in mucDestroyTest() Also add tryDestroy(muc). --- .../smackx/muc/MultiUserChatIntegrationTest.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java index ec18b6c56..89852a5fb 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java @@ -99,6 +99,12 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati MultiUserChat muc = mucManagerOne.getMultiUserChat(mucAddress); createMuc(muc, Resourcepart.from("one-" + randomString)); + // These would be a test implementation bug, not assertion failure. + if (!mucManagerOne.getJoinedRooms().contains(mucAddress)) { + tryDestroy(muc); + throw new IllegalStateException("Expected user to have joined a room '" + mucAddress + "' (but does not appear to have done so)."); + } + final SimpleResultSyncPoint mucDestroyed = new SimpleResultSyncPoint(); UserStatusListener userStatusListener = new UserStatusListener() { @@ -110,11 +116,6 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati muc.addUserStatusListener(userStatusListener); - // These would be a test implementation bug, not assertion failure. - if (!mucManagerOne.getJoinedRooms().contains(mucAddress)) { - throw new IllegalStateException("Expected user to have joined a room '" + mucAddress + "' (but does not appear to have done so)."); - } - try { muc.destroy("Dummy reason", null); assertResult(mucDestroyed, "Expected " + conOne.getUser() + " to be notified of destruction of room " + mucAddress + " (but was not)."); From 41022d139bb68a04d5593a35a0740d826e7147e7 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 21 May 2024 12:37:26 +0200 Subject: [PATCH 057/150] [sinttest] Improve assertion message of mucDestroyTest() Improve the assertion message of mucDestroyTest() by including the still joined rooms. --- .../jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java index 89852a5fb..b2ff930d6 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java @@ -19,6 +19,7 @@ package org.jivesoftware.smackx.muc; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; +import java.util.Set; import java.util.concurrent.TimeoutException; import org.jivesoftware.smack.MessageListener; @@ -123,7 +124,8 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati muc.removeUserStatusListener(userStatusListener); } - assertEquals(0, mucManagerOne.getJoinedRooms().size(), "Expected " + conOne.getUser() + " to no longer be in any rooms after " + mucAddress + " was destroyed (but was)."); + Set joinedRooms = mucManagerOne.getJoinedRooms(); + assertEquals(0, joinedRooms.size(), "Expected " + conOne.getUser() + " to no longer be in any rooms after " + mucAddress + " was destroyed. But it is still in " + joinedRooms); assertEquals(0, muc.getOccupantsCount(), "Expected room " + mucAddress + " to no longer have any occupants after it was destroyed (but it has)."); assertNull(muc.getNickname()); } From 2a5cf149b2e321722ee505e50b02e09b18fa6d90 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 21 May 2024 12:38:12 +0200 Subject: [PATCH 058/150] [sinttest] Use unique room names for mucJoinSemiAnonymousRoomReceivedBy*() In order to be able to identify potential room leaks, use unique rooms names for the two integration tests. Also destroy the room in mucJoinSemiAnonymousRoomReceivedByNonModeratorTest(). --- .../smackx/muc/MultiUserChatOccupantIntegrationTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java index 437b552bd..4caad88d9 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java @@ -379,7 +379,7 @@ public class MultiUserChatOccupantIntegrationTest extends AbstractMultiUserChatI "option), but MUST include the new occupant's full JID only in the presence notifications it sends to " + "occupants with a role of \"moderator\" and not to non-moderator occupants.") public void mucJoinSemiAnonymousRoomReceivedByNonModeratorTest() throws Exception { - EntityBareJid mucAddress = getRandomRoom("smack-inttest-joinsemianonymousroom"); + EntityBareJid mucAddress = getRandomRoom("smack-inttest-seminanonymous-by-non-moderator"); MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); @@ -408,7 +408,7 @@ public class MultiUserChatOccupantIntegrationTest extends AbstractMultiUserChatI // Check the presence received by participant two for exclusion of full jid of participant three assertNull(MUCUser.from(presenceReceivedByTwo).getItem().getJid(), "Did not expect '" + conTwo.getUser() + "' (who is not a moderator at this stage) to receive the full JID of '" + conThree.getUser() + "' when they joined room '" + mucAddress + "' (but they did)."); } finally { - mucAsSeenByThree.leave(); // Reset to have a second go + tryDestroy(mucAsSeenByOne); } } @@ -425,7 +425,7 @@ public class MultiUserChatOccupantIntegrationTest extends AbstractMultiUserChatI "option), but MUST include the new occupant's full JID only in the presence notifications it sends to " + "occupants with a role of \"moderator\" and not to non-moderator occupants.") public void mucJoinSemiAnonymousRoomReceivedByModeratorTest() throws Exception { - EntityBareJid mucAddress = getRandomRoom("smack-inttest-joinsemianonymousroom"); + EntityBareJid mucAddress = getRandomRoom("smack-inttest-seminanonymous-by-moderator"); MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); From 34c2d5210e41ab7e5e67f35002713190ecbb64c0 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 21 May 2024 12:50:19 +0200 Subject: [PATCH 059/150] [sinttest] Improve TimeoutException's message of ResultSyncPoint --- .../smack/inttest/util/ResultSyncPoint.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/ResultSyncPoint.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/ResultSyncPoint.java index f7f10b63f..ee691bf90 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/ResultSyncPoint.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/ResultSyncPoint.java @@ -1,6 +1,6 @@ /** * - * Copyright 2015 Florian Schmaus + * Copyright 2015-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,7 +50,12 @@ public class ResultSyncPoint { if (exception != null) { throw exception; } - throw new TimeoutException(timeoutMessage == null ? "Timeout expired" : timeoutMessage); + + String message = "Timeout after " + timeout + "ms"; + if (timeoutMessage != null) { + message += ": " + timeoutMessage; + } + throw new TimeoutException(message); } From 3749f524f5205b11aec0d7f98fa0ed3310f12f04 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 21 May 2024 13:06:58 +0200 Subject: [PATCH 060/150] [sinttest] Fix NPE by checking that status is not null testCurrentPresenceSentAfterSubscriptionApproval() --- .../jivesoftware/smack/roster/RosterIntegrationTest.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java index 091293c4d..28dff0ebf 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java @@ -1,6 +1,6 @@ /** * - * Copyright 2015-2020 Florian Schmaus, 2022-2024 Guus der Kinderen + * Copyright 2015-2024 Florian Schmaus, 2022-2024 Guus der Kinderen * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -412,7 +412,11 @@ public class RosterIntegrationTest extends AbstractSmackIntegrationTest { final SimpleResultSyncPoint received = new SimpleResultSyncPoint(); final StanzaListener stanzaListener = stanza -> { final Presence presence = (Presence) stanza; - if (presence.getStatus().equals(needle)) { + + String status = presence.getStatus(); + if (status == null) return; + + if (status.equals(needle)) { received.signal(); } }; From 1f34f3e613d3390962afbaf11903cd41986dbeaf Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 31 May 2024 23:09:35 +0200 Subject: [PATCH 061/150] [sinttest] Directly use rosterTwo instead of Roster.getInstanceFor() --- .../org/jivesoftware/smack/roster/RosterIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java index 28dff0ebf..91c11ea3e 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java @@ -142,7 +142,7 @@ public class RosterIntegrationTest extends AbstractSmackIntegrationTest { "whose value is \"subscribe\").") public void testRosterPushAfterSubscriptionRequest() throws Exception { IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); - Roster.getInstanceFor(conTwo).setSubscriptionMode(Roster.SubscriptionMode.manual); // prevents a race condition when asserting the captured roster entry. + rosterTwo.setSubscriptionMode(Roster.SubscriptionMode.manual); // prevents a race condition when asserting the captured roster entry. final ResultSyncPoint added = new ResultSyncPoint<>(); final RosterListener rosterListener = new AbstractRosterListener() { From 7acde2acabd622d6b5801e4c6693acdd9a68ab4a Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 31 May 2024 23:38:53 +0200 Subject: [PATCH 062/150] [sinttest] Drop testReceivePresenceAndApprovalAndRosterPush This tests reliably fails, not only for me. I suspect that it is related to the order of events checked by this tests, that can not be reliably tested, even with sync listeners. It is also is primarily a test for server behavior. --- .../smack/roster/RosterIntegrationTest.java | 66 ------------------- 1 file changed, 66 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java index 91c11ea3e..98db355c6 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java @@ -21,21 +21,15 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Collection; import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicBoolean; import org.jivesoftware.smack.StanzaListener; import org.jivesoftware.smack.filter.AndFilter; import org.jivesoftware.smack.filter.FromMatchesFilter; import org.jivesoftware.smack.filter.PresenceTypeFilter; import org.jivesoftware.smack.filter.StanzaTypeFilter; -import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler; -import org.jivesoftware.smack.iqrequest.IQRequestHandler; -import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.packet.PresenceBuilder; -import org.jivesoftware.smack.roster.packet.RosterPacket; import org.jivesoftware.smack.roster.packet.RosterPacket.ItemType; -import org.jivesoftware.smack.sm.predicates.ForEveryStanza; import org.jivesoftware.smack.util.Consumer; import org.jivesoftware.smack.util.StringUtils; @@ -437,64 +431,4 @@ public class RosterIntegrationTest extends AbstractSmackIntegrationTest { } } - /** - * Asserts that when a user receives a presence subscription approval, the server first sends the presence stanza, - * followed by a roster push. - * - * @throws Exception when errors occur - */ - @SmackIntegrationTest(section = "3.1.6", quote = - "(...) If this check is successful, then the user's server MUST: 1. Deliver the inbound subscription " + - "approval to all of the user's interested resources (...). This MUST occur before sending the roster push " + - "described in the next step. 2. Initiate a roster push to all of the user's interested resources, containing " + - "an updated roster item for the contact with the 'subscription' attribute set to a value of \"to\" (...) or " + - "\"both\" (...).") - public void testReceivePresenceApprovalAndRosterPush() throws Exception { - IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); - - rosterTwo.setSubscriptionMode(Roster.SubscriptionMode.accept_all); - - final ResultSyncPoint receivedRosterPush = new ResultSyncPoint<>(); - final AtomicBoolean hasReceivedSubscriptionApproval = new AtomicBoolean(false); - - // Replace the IQ Request Handler that processes roster pushes with one that's guaranteed to be executed - // synchronously with the stanza handler that listens for presence updates (below). This is to guarantee that - // the order in which both stanzas arrive is maintained during processing. - final IQRequestHandler synchronousReplacement = new AbstractIqRequestHandler(RosterPacket.ELEMENT, RosterPacket.NAMESPACE, IQ.Type.set, IQRequestHandler.Mode.sync) { - @Override - public IQ handleIQRequest(IQ iqRequest) { - receivedRosterPush.signal(hasReceivedSubscriptionApproval.get()); - return IQ.createResultIQ(iqRequest); - } - }; - final IQRequestHandler originalRequestHandler = conOne.registerIQRequestHandler(synchronousReplacement); - - final StanzaListener presenceUpdateListener = stanza -> { - if (stanza instanceof Presence) { - final Presence presence = (Presence) stanza; - if (presence.getType() == Presence.Type.subscribed) { - hasReceivedSubscriptionApproval.set(true); - } - } - }; - - // Add as a synchronous listener, again to guarantee to maintain the order of the stanzas captured by this - // listener and the roster pushes captured by the IQ Request Handler (above). - conOne.addSyncStanzaListener(presenceUpdateListener, ForEveryStanza.INSTANCE); - - final Presence subscribe = conOne.getStanzaFactory().buildPresenceStanza() - .ofType(Presence.Type.subscribe) - .to(conTwo.getUser().asBareJid()) - .build(); - - try { - conOne.sendStanza(subscribe); - final boolean hasReceivedApproval = assertResult(receivedRosterPush, "Expected '" + conOne.getUser() + "' to receive a roster push containing an updated roster entry for '" + conTwo.getUser().asBareJid() + "'"); - assertTrue(hasReceivedApproval, "Expected '" + conOne.getUser() + "' to have received a presence subscription approval from '" + conTwo.getUser().asBareJid() + "', before it received the roster push that contained the updated contact, but the presence subscription approval was not (yet) received when the roster push was."); - } finally { - rosterOne.setSubscriptionMode(Roster.getDefaultSubscriptionMode()); - conOne.removeSyncStanzaListener(presenceUpdateListener); - conOne.registerIQRequestHandler(originalRequestHandler); - } - } } From 4ce926bd63ca6e94998fce27264dc47463f4473f Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 31 May 2024 23:43:43 +0200 Subject: [PATCH 063/150] [core] Use StanzaView as StanzaIdFilter constructor parameter type Instead of Stanza, use StanzaView as constructor parameter type of StanzaIdFilter. Even though StanzaView also includes builders, the Stanza ID is even immutable in builders. --- .../java/org/jivesoftware/smack/filter/StanzaIdFilter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/StanzaIdFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/StanzaIdFilter.java index c0d507e50..8e5a5cc2c 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/StanzaIdFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/StanzaIdFilter.java @@ -18,6 +18,7 @@ package org.jivesoftware.smack.filter; import org.jivesoftware.smack.packet.Stanza; +import org.jivesoftware.smack.packet.StanzaView; import org.jivesoftware.smack.util.StringUtils; /** @@ -34,7 +35,7 @@ public class StanzaIdFilter implements StanzaFilter { * * @param stanza the stanza which the ID is taken from. */ - public StanzaIdFilter(Stanza stanza) { + public StanzaIdFilter(StanzaView stanza) { this(stanza.getStanzaId()); } From 147071ff643971b4d873ddbdb16e347e4e353652 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 1 Jun 2024 00:06:56 +0200 Subject: [PATCH 064/150] [muc] Fix changeSubject() to throw XMPPErrorException on failures When Smack requests a subject change of a MUC, an error returned by the server (eg: 'forbidden') should be propagated (as suggested by the pre-existing javadoc). Reported-by: Guus der Kinderen --- .../org/jivesoftware/smackx/muc/MultiUserChat.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java index 5c3f687c4..45d474749 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java @@ -2248,17 +2248,20 @@ public class MultiUserChat { * @throws InterruptedException if the calling thread was interrupted. */ public void changeSubject(final String subject) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - MessageBuilder message = buildMessage(); - message.setSubject(subject); + Message message = buildMessage() + .setSubject(subject) + .build(); // Wait for an error or confirmation message back from the server. - StanzaFilter responseFilter = new AndFilter(fromRoomGroupchatFilter, new StanzaFilter() { + StanzaFilter successFilter = new AndFilter(fromRoomGroupchatFilter, new StanzaFilter() { @Override public boolean accept(Stanza packet) { Message msg = (Message) packet; return subject.equals(msg.getSubject()); } }); - StanzaCollector response = connection.createStanzaCollectorAndSend(responseFilter, message.build()); + StanzaFilter errorFilter = new AndFilter(fromRoomFilter, new StanzaIdFilter(message), MessageTypeFilter.ERROR); + StanzaFilter responseFilter = new OrFilter(successFilter, errorFilter); + StanzaCollector response = connection.createStanzaCollectorAndSend(responseFilter, message); // Wait up to a certain number of seconds for a reply. response.nextResultOrThrow(); } From a7083872101454f6dde10d6d69e546be3115ad9b Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 1 Jun 2024 11:24:43 +0200 Subject: [PATCH 065/150] [muc] Add roomconfig_changesubject support to MucConfigFormManager --- .../smackx/muc/MucConfigFormManager.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java index 9f2778e9c..f46124482 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java @@ -25,6 +25,7 @@ import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smackx.muc.MultiUserChatException.MucConfigurationNotSupportedException; +import org.jivesoftware.smackx.xdata.BooleanFormField; import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.form.FillableForm; import org.jivesoftware.smackx.xdata.form.FilledForm; @@ -98,6 +99,11 @@ public class MucConfigFormManager { */ public static final String MUC_ROOMCONFIG_ENABLE_PUBLIC_LOGGING = "muc#roomconfig_enablelogging"; + /** + * The constant String {@value}. + */ + public static final String MUC_ROOMCONFIG_CHANGE_SUBJECT = "muc#roomconfig_changesubject"; + private final MultiUserChat multiUserChat; private final FillableForm answerForm; private final List owners; @@ -374,6 +380,33 @@ public class MucConfigFormManager { return this; } + public boolean supportsChangeSubjectByOccupant() { + return answerForm.hasField(MUC_ROOMCONFIG_CHANGE_SUBJECT); + } + + public boolean occupantsAreAllowedToChangeSubject() throws MucConfigurationNotSupportedException { + if (!supportsChangeSubjectByOccupant()) { + throw new MucConfigurationNotSupportedException(MUC_ROOMCONFIG_CHANGE_SUBJECT); + } + return answerForm.getField(MUC_ROOMCONFIG_CHANGE_SUBJECT).ifPossibleAsOrThrow(BooleanFormField.class).getValueAsBoolean(); + } + + public MucConfigFormManager setChangeSubjectByOccupant(boolean enabled) throws MucConfigurationNotSupportedException { + if (!supportsChangeSubjectByOccupant()) { + throw new MucConfigurationNotSupportedException(MUC_ROOMCONFIG_CHANGE_SUBJECT); + } + answerForm.setAnswer(MUC_ROOMCONFIG_CHANGE_SUBJECT, enabled); + return this; + } + + public MucConfigFormManager allowOccupantsToChangeSubject() throws MucConfigurationNotSupportedException { + return setChangeSubjectByOccupant(true); + } + + public MucConfigFormManager disallowOccupantsToChangeSubject() throws MucConfigurationNotSupportedException { + return setChangeSubjectByOccupant(false); + } + /** * Submit the configuration as {@link FilledForm} to the room. * From 6ae8234d255bcf6e19a5faf50d70a2892f35b0b4 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 1 Jun 2024 11:25:08 +0200 Subject: [PATCH 066/150] [sinttest] Add MultiUserChatIntegrationTest.mucTestVisitorNotAllowedToChangeSubject --- .../muc/MultiUserChatIntegrationTest.java | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java index b2ff930d6..5d938bff5 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java @@ -1,6 +1,6 @@ /** * - * Copyright 2015-2020 Florian Schmaus + * Copyright 2015-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.jivesoftware.smackx.muc; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.util.Set; import java.util.concurrent.TimeoutException; @@ -29,6 +30,7 @@ import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.StanzaError; import org.jivesoftware.smackx.muc.MultiUserChatException.MissingMucCreationAcknowledgeException; import org.jivesoftware.smackx.muc.MultiUserChatException.MucAlreadyJoinedException; import org.jivesoftware.smackx.muc.MultiUserChatException.MucConfigurationNotSupportedException; @@ -154,4 +156,41 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati tryDestroy(muc); } } + + @SmackIntegrationTest(section = "8.1", quote = "modify the subject [...] MUST be denied if the of the 'from' address of the request does not match " + + "the bare JID portion of one of the moderators; in this case, the service MUST return a error.") + public void mucTestVisitorNotAllowedToChangeSubject() throws XmppStringprepException, MucAlreadyJoinedException, + MissingMucCreationAcknowledgeException, NotAMucServiceException, NoResponseException, + XMPPErrorException, NotConnectedException, InterruptedException, TestNotPossibleException { + final EntityBareJid mucAddress = getRandomRoom("smack-inttest-visitor-change-subject"); + final MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); + final MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress); + + final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString); + final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString); + + createMuc(mucAsSeenByOne, nicknameOne); + try { + MucConfigFormManager configFormManager = mucAsSeenByOne.getConfigFormManager(); + if (configFormManager.occupantsAreAllowedToChangeSubject()) { + configFormManager.disallowOccupantsToChangeSubject().submitConfigurationForm(); + } + + mucAsSeenByTwo.join(nicknameTwo); + + final XMPPException.XMPPErrorException e = assertThrows(XMPPException.XMPPErrorException.class, () -> { + mucAsSeenByTwo.changeSubject("Test Subject Change"); + }, "Expected an error after '" + conTwo.getUser() + + "' (that is not a moderator) tried to change the subject of room '" + mucAddress + + "' (but none occurred)."); + assertEquals(StanzaError.Condition.forbidden, e.getStanzaError().getCondition(), + "Unexpected error condition in the (expected) error that was returned to '" + + conTwo.getUser() + "' after it tried to change to subject of room '" + + mucAddress + "' while not being a moderator."); + } catch (MucConfigurationNotSupportedException e) { + throw new TestNotPossibleException(e); + } finally { + tryDestroy(mucAsSeenByOne); + } + } } From b2331aaacfe522d18a9096df3eb4fb0df30e37d1 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 1 Jun 2024 12:13:33 +0200 Subject: [PATCH 067/150] [sinttest] Throw IllegalArgumentException if no tests have been selected --- .../smack/inttest/SmackIntegrationTestFramework.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java index 3db80163f..070974a67 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java @@ -527,6 +527,11 @@ public class SmackIntegrationTestFramework { } sb.append('\n'); } + + if (numberOfAvailableTests == 0) { + throw new IllegalArgumentException("No integration tests selected."); + } + sb.append("Available tests: ").append(numberOfAvailableTests); if (!testRunResult.disabledTestClasses.isEmpty() || !testRunResult.disabledTests.isEmpty()) { sb.append(" (Disabled ").append(testRunResult.disabledTestClasses.size()).append(" classes") From 5cbcd676457ca9429f3788ab7e77681171fbc50d Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 1 Jun 2024 12:14:02 +0200 Subject: [PATCH 068/150] [sinttest] Add MultiUserChatIntegrationTest.mucTestChangeRoomName --- .../muc/MultiUserChatIntegrationTest.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java index 5d938bff5..9dcd73e68 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java @@ -193,4 +193,30 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati tryDestroy(mucAsSeenByOne); } } + + @SmackIntegrationTest + public void mucTestChangeRoomName() throws XmppStringprepException, MucAlreadyJoinedException, + MissingMucCreationAcknowledgeException, NotAMucServiceException, NoResponseException, + XMPPErrorException, NotConnectedException, InterruptedException, TestNotPossibleException { + final EntityBareJid mucAddress = getRandomRoom("smack-inttest-change-room-name"); + final MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress); + final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString); + + createMuc(mucAsSeenByOne, nicknameOne); + try { + String initialRoomName = "Initial Room Name"; + mucAsSeenByOne.getConfigFormManager().setRoomName(initialRoomName).submitConfigurationForm(); + RoomInfo roomInfo = mucManagerOne.getRoomInfo(mucAddress); + assertEquals(initialRoomName, roomInfo.getName()); + + String newRoomName = "New Room Name"; + mucAsSeenByOne.getConfigFormManager().setRoomName(newRoomName).submitConfigurationForm(); + roomInfo = mucManagerOne.getRoomInfo(mucAddress); + assertEquals(newRoomName, roomInfo.getName()); + } catch (MucConfigurationNotSupportedException e) { + throw new TestNotPossibleException(e); + } finally { + tryDestroy(mucAsSeenByOne); + } + } } From 7c77cfbc205fe3b1f895c0626314ba37808e8438 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Fri, 7 Jun 2024 15:45:23 +0200 Subject: [PATCH 069/150] [sinttest] Add new config option: 'host' An optional configuration option for the Smack Integration Test framework has been added that allows one to bypass DNS when resolving a host for the XMPP domain that is the subject of the test. The `host` option can be used with IP addresses (eg: `-Dsinttest.host=127.0.0.1`) and DNS names (eg: `-Dsinttest.host=example.org`). --- .../smack/inttest/Configuration.java | 14 ++++++++++++++ .../igniterealtime/smack/inttest/package-info.java | 4 ++++ 2 files changed, 18 insertions(+) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java index 48a587cc5..0616da38a 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java @@ -72,6 +72,8 @@ public final class Configuration { public final DomainBareJid service; + public final String host; + public final String serviceTlsPin; public final SslContextFactory sslContextFactory; @@ -138,6 +140,7 @@ public final class Configuration { private Configuration(Configuration.Builder builder) throws KeyManagementException, NoSuchAlgorithmException { service = Objects.requireNonNull(builder.service, "'service' must be set. Either via 'properties' files or via system property 'sinttest.service'."); + host = builder.host; serviceTlsPin = builder.serviceTlsPin; if (serviceTlsPin != null) { SSLContext sslContext = Java7Pinning.forPin(serviceTlsPin); @@ -197,6 +200,9 @@ public final class Configuration { } b.setSecurityMode(securityMode); b.setXmppDomain(service); + if (host != null) { + b.setHost(host); + } if (debuggerFactory != null) { b.setDebuggerFactory(debuggerFactory); @@ -222,6 +228,8 @@ public final class Configuration { private DomainBareJid service; + private String host; + private String serviceTlsPin; private SecurityMode securityMode; @@ -287,6 +295,11 @@ public final class Configuration { return this; } + private Builder setHost(String host) { + this.host = host; + return this; + } + public Builder addEnabledTest(Class enabledTest) { if (enabledTests == null) { enabledTests = new HashSet<>(); @@ -521,6 +534,7 @@ public final class Configuration { Builder builder = builder(); builder.setService(properties.getProperty("service")); + builder.setHost(properties.getProperty("host")); builder.setServiceTlsPin(properties.getProperty("serviceTlsPin")); builder.setSecurityMode(properties.getProperty("securityMode")); builder.setReplyTimeout(properties.getProperty("replyTimeout", "47000")); diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java index c72d0afc2..22ad207f5 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java @@ -80,6 +80,10 @@ * XMPP service to run the tests on * * + * host + * IP address or DNS name of the XMPP service to run the tests on + * + * * serviceTlsPin * TLS Pin (used by java-pinning) * From 4eafb0ceeb63e11bdc7658dd11413a27c16844f1 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 2 May 2024 16:20:12 +0200 Subject: [PATCH 070/150] [sinttest] Add version to specref for XEP-0115 The test was implemented when version 1.5.1 of the XEP was the most current version. Later versions of the XEP do not significantly modify the specifications, making it plausible that this implementation matches the current version of the XEP: 1.6.0. --- .../main/java/org/jivesoftware/smackx/caps/EntityCapsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/caps/EntityCapsTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/caps/EntityCapsTest.java index c18ea490b..74d9aa6a8 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/caps/EntityCapsTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/caps/EntityCapsTest.java @@ -54,7 +54,7 @@ import org.igniterealtime.smack.inttest.annotations.BeforeClass; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; import org.igniterealtime.smack.inttest.annotations.SpecificationReference; -@SpecificationReference(document = "XEP-0115") +@SpecificationReference(document = "XEP-0115", version = "1.6.0") public class EntityCapsTest extends AbstractSmackIntegrationTest { private final EntityCapsManager ecmTwo; From febb0e8f24d5fce53e4634b222a346c301498bd1 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 2 May 2024 16:25:21 +0200 Subject: [PATCH 071/150] [sinttest] Add version to specref for XEP-0085 The test was implemented years after the most current version of the XEP was published, making it plausible that the implementation matches that version of the XEP: 2.1. --- .../jivesoftware/smackx/chatstate/ChatStateIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/chatstate/ChatStateIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/chatstate/ChatStateIntegrationTest.java index 749b39caf..2c1b56e1a 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/chatstate/ChatStateIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/chatstate/ChatStateIntegrationTest.java @@ -30,7 +30,7 @@ import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; -@SpecificationReference(document = "XEP-0085") +@SpecificationReference(document = "XEP-0085", version = "2.1") public class ChatStateIntegrationTest extends AbstractSmackIntegrationTest { // Listener for composing chat state From 74614b00f7a77940fd35d8d45ad4a169f1f2315f Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 2 May 2024 16:27:09 +0200 Subject: [PATCH 072/150] [sinttest] Add version to specref for XEP-0050 The test was implemented years after the most current version of the XEP was published, making it plausible that the implementation matches that version of the XEP: 1.3.0. --- .../smackx/commands/AdHocCommandIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandIntegrationTest.java index 3e2b55516..1ece51611 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandIntegrationTest.java @@ -38,7 +38,7 @@ import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; import org.igniterealtime.smack.inttest.annotations.SpecificationReference; -@SpecificationReference(document = "XEP-0050") +@SpecificationReference(document = "XEP-0050", version = "1.3.0") public class AdHocCommandIntegrationTest extends AbstractSmackIntegrationTest { public AdHocCommandIntegrationTest(SmackIntegrationTestEnvironment environment) { From 973f37996f9489bef5d114e5cad266091ff3464a Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 2 May 2024 16:30:39 +0200 Subject: [PATCH 073/150] [sinttest] Add version to specref for XEP-0096 The test was implemented when version 1.2 of the XEP was the most current version. Later versions of the XEP do not significantly modify the specifications, making it plausible that this implementation matches the current version of the XEP: 1.3.1. --- .../smackx/filetransfer/FileTransferIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferIntegrationTest.java index f2addc2ae..25ebb9b2a 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferIntegrationTest.java @@ -34,7 +34,7 @@ import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; -@SpecificationReference(document = "XEP-0096") +@SpecificationReference(document = "XEP-0096", version = "1.3.1") public class FileTransferIntegrationTest extends AbstractSmackIntegrationTest { private static final int MAX_FT_DURATION = 360; From cdbc431cddf886f1e8f943d11749b57c0d1ab023 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 2 May 2024 16:31:55 +0200 Subject: [PATCH 074/150] [sinttest] Add version to specref for XEP-0080 The test was implemented years after the most current version of the XEP was published, making it plausible that the implementation matches that version of the XEP: 1.9. --- .../smackx/geolocation/GeolocationIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/geolocation/GeolocationIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/geolocation/GeolocationIntegrationTest.java index b58c04b71..f7e708775 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/geolocation/GeolocationIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/geolocation/GeolocationIntegrationTest.java @@ -38,7 +38,7 @@ import org.igniterealtime.smack.inttest.util.IntegrationTestRosterUtil; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; import org.jxmpp.util.XmppDateTime; -@SpecificationReference(document = "XEP-0080") +@SpecificationReference(document = "XEP-0080", version = "1.9") public class GeolocationIntegrationTest extends AbstractSmackIntegrationTest { private final GeoLocationManager glm1; From f5e5b4a913fccb013dac8116dfe812b7c5f68972 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 2 May 2024 16:49:45 +0200 Subject: [PATCH 075/150] [sinttest] Add version to specref for XEP-0363 The test was implemented when version 0.3.1 of the XEP was the most current version. The Smack code that is being tested defines a namespace that was introduced in 0.4.0, making it plausible that this implementation matches that version of the XEP: 0.4.0 (which is _not_ the latest version of the XEP). --- .../smackx/httpfileupload/HttpFileUploadIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/httpfileupload/HttpFileUploadIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/httpfileupload/HttpFileUploadIntegrationTest.java index 8c92d8f1c..f68ab7b61 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/httpfileupload/HttpFileUploadIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/httpfileupload/HttpFileUploadIntegrationTest.java @@ -38,7 +38,7 @@ import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; import org.igniterealtime.smack.inttest.annotations.SpecificationReference; -@SpecificationReference(document = "XEP-0363") +@SpecificationReference(document = "XEP-0363", version = "0.4.0") public class HttpFileUploadIntegrationTest extends AbstractSmackIntegrationTest { private static final int FILE_SIZE = 1024 * 128; From 8b20d4b38275e220968f4faf497bba22d67362f6 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 2 May 2024 16:54:27 +0200 Subject: [PATCH 076/150] [sinttest] Add version to specref for XEP-0347 The test was implemented when version 0.4 of the XEP was the most current version. Later versions of the XEP do not significantly modify the specifications, making it plausible that this implementation matches the current version of the XEP: 0.5.1. --- .../org/jivesoftware/smackx/iot/IoTControlIntegrationTest.java | 2 +- .../org/jivesoftware/smackx/iot/IoTDataIntegrationTest.java | 2 +- .../jivesoftware/smackx/iot/IoTDiscoveryIntegrationTest.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTControlIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTControlIntegrationTest.java index 903e17810..4d4844adf 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTControlIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTControlIntegrationTest.java @@ -38,7 +38,7 @@ import org.igniterealtime.smack.inttest.util.IntegrationTestRosterUtil; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; import org.jxmpp.jid.Jid; -@SpecificationReference(document = "XEP-0347") +@SpecificationReference(document = "XEP-0347", version = "0.5.1") public class IoTControlIntegrationTest extends AbstractSmackIntegrationTest { private final IoTControlManager IoTControlManagerOne; diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDataIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDataIntegrationTest.java index fe4e39124..731260475 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDataIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDataIntegrationTest.java @@ -40,7 +40,7 @@ import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.IntegrationTestRosterUtil; -@SpecificationReference(document = "XEP-0347") +@SpecificationReference(document = "XEP-0347", version = "0.5.1") public class IoTDataIntegrationTest extends AbstractSmackIntegrationTest { private final IoTDataManager iotDataManagerOne; diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDiscoveryIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDiscoveryIntegrationTest.java index 911259040..7c3f3dcac 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDiscoveryIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iot/IoTDiscoveryIntegrationTest.java @@ -37,7 +37,7 @@ import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.jxmpp.jid.Jid; -@SpecificationReference(document = "XEP-0347") +@SpecificationReference(document = "XEP-0347", version = "0.5.1") public class IoTDiscoveryIntegrationTest extends AbstractSmackIntegrationTest { private final IoTDiscoveryManager discoveryManagerOne; From b753c4a876066c0112ca50e82523d8cbb22a4514 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 2 May 2024 16:55:39 +0200 Subject: [PATCH 077/150] [sinttest] Add version to specref for XEP-0092 The test was implemented years after the most current version of the XEP was published, making it plausible that the implementation matches that version of the XEP: 1.1. --- .../jivesoftware/smackx/iqversion/VersionIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iqversion/VersionIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iqversion/VersionIntegrationTest.java index dd44d8c03..05c8fa18d 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/iqversion/VersionIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/iqversion/VersionIntegrationTest.java @@ -30,7 +30,7 @@ import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; import org.igniterealtime.smack.inttest.annotations.SpecificationReference; -@SpecificationReference(document = "XEP-0092") +@SpecificationReference(document = "XEP-0092", version = "1.1") public class VersionIntegrationTest extends AbstractSmackIntegrationTest { public VersionIntegrationTest(SmackIntegrationTestEnvironment environment) { From 8d66f78b3b9cd6cce4f1bad86172fd85b7a8347a Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 2 May 2024 17:03:33 +0200 Subject: [PATCH 078/150] [sinttest] Add version to specref for XEP-0363 The test was originally implemented when version 0.5.1 of the XEP was the most current version. The Smack code that is being tested defines a namespace that was introduced in 0.6, making it plausible that this implementation matches the version of the XEP, followed by some editorial changes: 0.6.3 (which is _not_ the latest version of the XEP). --- .../java/org/jivesoftware/smackx/mam/MamIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 cb1ebe12b..9b9cba7a3 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 @@ -46,7 +46,7 @@ import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; import org.jxmpp.jid.EntityBareJid; -@SpecificationReference(document = "XEP-0313") +@SpecificationReference(document = "XEP-0313", version = "0.6.3") public class MamIntegrationTest extends AbstractSmackIntegrationTest { private final MamManager mamManagerConTwo; From 268c298264561ba4aa23f6922c345c2e4861de31 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 2 May 2024 17:04:02 +0200 Subject: [PATCH 079/150] [sinttest] Add version to specref for XEP-0107 The test was implemented after the most current version of the XEP was published, making it plausible that the implementation matches that version of the XEP: 1.2.1 --- .../java/org/jivesoftware/smackx/mood/MoodIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/mood/MoodIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/mood/MoodIntegrationTest.java index ca30cbca2..9b1dfeacd 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/mood/MoodIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/mood/MoodIntegrationTest.java @@ -32,7 +32,7 @@ import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.IntegrationTestRosterUtil; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; -@SpecificationReference(document = "XEP-0107") +@SpecificationReference(document = "XEP-0107", version = "1.2.1") public class MoodIntegrationTest extends AbstractSmackIntegrationTest { private final MoodManager mm1; From f78766ad6eb43af04d25923093707c2fbf7adb1f Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 2 May 2024 17:15:54 +0200 Subject: [PATCH 080/150] [sinttest] Add version to specref for XEP-0045 (section 6) The test was implemented when version 1.34.2 of the XEP was the most current version. Later versions of the XEP do not significantly modify the specifications, making it plausible that this implementation matches the current version of the XEP: 1.34.6. --- .../smackx/muc/MultiUserChatEntityIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java index 0a8dcf175..54083165b 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java @@ -43,7 +43,7 @@ import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityFullJid; import org.jxmpp.jid.parts.Resourcepart; -@SpecificationReference(document = "XEP-0045") +@SpecificationReference(document = "XEP-0045", version = "1.34.6") public class MultiUserChatEntityIntegrationTest extends AbstractMultiUserChatIntegrationTest { public MultiUserChatEntityIntegrationTest(SmackIntegrationTestEnvironment environment) From 963c25799a6c3190af019ba2859dae95c78dd4de Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 2 May 2024 17:17:28 +0200 Subject: [PATCH 081/150] [sinttest] Add version to specref for XEP-0045 (section 7) The test was implemented when version 1.34.1 of the XEP was the most current version. Later versions of the XEP do not significantly modify the specifications, making it plausible that this implementation matches the current version of the XEP: 1.34.6. --- .../smackx/muc/MultiUserChatOccupantIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java index 4caad88d9..e478282f2 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java @@ -55,7 +55,7 @@ import org.jxmpp.jid.EntityFullJid; import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.parts.Resourcepart; -@SpecificationReference(document = "XEP-0045") +@SpecificationReference(document = "XEP-0045", version = "1.34.6") public class MultiUserChatOccupantIntegrationTest extends AbstractMultiUserChatIntegrationTest { public MultiUserChatOccupantIntegrationTest(SmackIntegrationTestEnvironment environment) From 03ee544e0ed343e2b74021811371c63fde108cbd Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 2 May 2024 17:19:18 +0200 Subject: [PATCH 082/150] [sinttest] Add version to specref for XEP-0045 (section 5) The test was implemented when version 1.34.1 of the XEP was the most current version. Later versions of the XEP do not significantly modify the specifications, making it plausible that this implementation matches the current version of the XEP: 1.34.6. --- ...MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java index 53b44765c..9c4eab22b 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java @@ -47,7 +47,7 @@ import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.parts.Resourcepart; -@SpecificationReference(document = "XEP-0045") +@SpecificationReference(document = "XEP-0045", version = "1.34.6") public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends AbstractMultiUserChatIntegrationTest{ public MultiUserChatRolesAffiliationsPrivilegesIntegrationTest(SmackIntegrationTestEnvironment environment) From 9e0f20b74824d3217429ef79f01bf014b9d164b3 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Wed, 12 Jun 2024 17:18:21 +0200 Subject: [PATCH 083/150] [sinttest] Add version to specref for XEP-0045 The test was originally implemented when version 1.25 of the XEP was the most current version. Later versions of the XEP do significantly modify the specifications, but the test implementation has had continuous changes over time too. This makes it plausible that this implementation matches the current version of the XEP: 1.34.6. --- .../jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java index 9dcd73e68..406f5e164 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java @@ -45,7 +45,7 @@ import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.parts.Resourcepart; import org.jxmpp.stringprep.XmppStringprepException; -@SpecificationReference(document = "XEP-0045") +@SpecificationReference(document = "XEP-0045", version = "1.34.6") public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrationTest { public MultiUserChatIntegrationTest(SmackIntegrationTestEnvironment environment) From 6b912f9aba17531de2fba21198f087ee4a563305 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Wed, 12 Jun 2024 17:25:20 +0200 Subject: [PATCH 084/150] [sinttest] Add version to specref for XEP-0048 The test was originally implemented when version 1.1 of the XEP was the most current version. Later versions of the XEP do not significantly modify the specifications, making it plausible that this implementation matches the current version of the XEP: 1.2. --- .../smackx/muc/MultiUserChatLowLevelIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatLowLevelIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatLowLevelIntegrationTest.java index e77bc40cc..3b81ce840 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatLowLevelIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatLowLevelIntegrationTest.java @@ -39,7 +39,7 @@ import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.parts.Localpart; import org.jxmpp.jid.parts.Resourcepart; -@SpecificationReference(document = "XEP-0048") +@SpecificationReference(document = "XEP-0048", version = "1.2") public class MultiUserChatLowLevelIntegrationTest extends AbstractSmackLowLevelIntegrationTest { public MultiUserChatLowLevelIntegrationTest(SmackIntegrationTestEnvironment environment) throws Exception { From 7e153d87d046923fba7cf652feefa19642d98181 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Wed, 12 Jun 2024 17:31:00 +0200 Subject: [PATCH 085/150] [sinttest] Add version to specref for XEP-0384 These tests were originally implemented when versions 0.2.1 and 0.3.0 of the XEP were the most current version. Later versions of the XEP do significantly modify the specifications, making it plausible that this implementation matches the version of the XEP that was the most recent version at the time the test was created: 0.3.0 --- .../smackx/omemo/MessageEncryptionIntegrationTest.java | 2 +- .../org/jivesoftware/smackx/omemo/OmemoMamDecryptionTest.java | 2 +- .../smackx/omemo/ReadOnlyDeviceIntegrationTest.java | 2 +- .../smackx/omemo/SessionRenegotiationIntegrationTest.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/MessageEncryptionIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/MessageEncryptionIntegrationTest.java index a8d5fe441..5b489aef7 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/MessageEncryptionIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/MessageEncryptionIntegrationTest.java @@ -36,7 +36,7 @@ import org.igniterealtime.smack.inttest.annotations.SpecificationReference; * During this test Alice sends an encrypted message to Bob. Bob decrypts it and sends a response to Alice. * It is checked whether the messages can be decrypted, and if used up pre-keys result in renewed bundles. */ -@SpecificationReference(document = "XEP-0384") +@SpecificationReference(document = "XEP-0384", version = "0.3.0") public class MessageEncryptionIntegrationTest extends AbstractTwoUsersOmemoIntegrationTest { public MessageEncryptionIntegrationTest(SmackIntegrationTestEnvironment environment) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMamDecryptionTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMamDecryptionTest.java index ff46adc8a..f14fd1990 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMamDecryptionTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMamDecryptionTest.java @@ -41,7 +41,7 @@ import org.igniterealtime.smack.inttest.annotations.SpecificationReference; * This test sends a message from Alice to Bob, while Bob has automatic decryption disabled. * Then Bob fetches his Mam archive and decrypts the result. */ -@SpecificationReference(document = "XEP-0384") +@SpecificationReference(document = "XEP-0384", version = "0.3.0") public class OmemoMamDecryptionTest extends AbstractTwoUsersOmemoIntegrationTest { public OmemoMamDecryptionTest(SmackIntegrationTestEnvironment environment) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/ReadOnlyDeviceIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/ReadOnlyDeviceIntegrationTest.java index ee593c012..b4daa8640 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/ReadOnlyDeviceIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/ReadOnlyDeviceIntegrationTest.java @@ -34,7 +34,7 @@ import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; import org.igniterealtime.smack.inttest.annotations.SpecificationReference; -@SpecificationReference(document = "XEP-0384") +@SpecificationReference(document = "XEP-0384", version = "0.3.0") public class ReadOnlyDeviceIntegrationTest extends AbstractTwoUsersOmemoIntegrationTest { public ReadOnlyDeviceIntegrationTest(SmackIntegrationTestEnvironment environment) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, TestNotPossibleException { diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/SessionRenegotiationIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/SessionRenegotiationIntegrationTest.java index e8a48fd7b..0b3b15e79 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/SessionRenegotiationIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/SessionRenegotiationIntegrationTest.java @@ -26,7 +26,7 @@ import org.igniterealtime.smack.inttest.TestNotPossibleException; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; import org.igniterealtime.smack.inttest.annotations.SpecificationReference; -@SpecificationReference(document = "XEP-0384") +@SpecificationReference(document = "XEP-0384", version = "0.3.0") public class SessionRenegotiationIntegrationTest extends AbstractTwoUsersOmemoIntegrationTest { public SessionRenegotiationIntegrationTest(SmackIntegrationTestEnvironment environment) From a40dd35eeb44849c11b751115ba3e66861326256 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Wed, 12 Jun 2024 17:34:14 +0200 Subject: [PATCH 086/150] [sinttest] Add version to specref for XEP-0374 The test was originally implemented when version 0.1.2 of the XEP was the most current version. Later versions of the XEP do not significantly modify the specifications, making it plausible that this implementation matches the current version of the XEP: 0.2.0. --- .../smackx/ox/OXSecretKeyBackupIntegrationTest.java | 2 +- .../smackx/ox_im/OXInstantMessagingIntegrationTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/OXSecretKeyBackupIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/OXSecretKeyBackupIntegrationTest.java index dc64db3a9..0aa708e9f 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/OXSecretKeyBackupIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/OXSecretKeyBackupIntegrationTest.java @@ -52,7 +52,7 @@ import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.pgpainless.key.OpenPgpV4Fingerprint; import org.pgpainless.key.protection.UnprotectedKeysProtector; -@SpecificationReference(document = "XEP-0374") +@SpecificationReference(document = "XEP-0374", version = "0.2.0") public class OXSecretKeyBackupIntegrationTest extends AbstractOpenPgpIntegrationTest { private static final String sessionId = StringUtils.randomString(10); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingIntegrationTest.java index cb5e914af..0dc597853 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingIntegrationTest.java @@ -45,7 +45,7 @@ import org.pgpainless.decryption_verification.OpenPgpMetadata; import org.pgpainless.key.OpenPgpV4Fingerprint; import org.pgpainless.key.protection.UnprotectedKeysProtector; -@SpecificationReference(document = "XEP-0374") +@SpecificationReference(document = "XEP-0374", version = "0.2.0") public class OXInstantMessagingIntegrationTest extends AbstractOpenPgpIntegrationTest { private static final String sessionId = StringUtils.randomString(10); From 2a6e6c715423badb6c01245474db5db540bed8eb Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Wed, 12 Jun 2024 17:35:46 +0200 Subject: [PATCH 087/150] [sinttest] Add version to specref for XEP-0199 The test was originally implemented when version 2.0 of the XEP was the most current version. Later versions of the XEP do not significantly modify the specifications, making it plausible that this implementation matches the current version of the XEP: 2.0.1. --- .../java/org/jivesoftware/smackx/ping/PingIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ping/PingIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ping/PingIntegrationTest.java index 035b9ed32..a2cbce7ce 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ping/PingIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ping/PingIntegrationTest.java @@ -38,7 +38,7 @@ import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.jxmpp.jid.Jid; -@SpecificationReference(document = "XEP-0199") +@SpecificationReference(document = "XEP-0199", version = "2.0.1") public class PingIntegrationTest extends AbstractSmackIntegrationTest { public PingIntegrationTest(SmackIntegrationTestEnvironment environment) { From 3f0933e90ee40b039a4353834708564775221d65 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Wed, 12 Jun 2024 17:38:35 +0200 Subject: [PATCH 088/150] [sinttest] Add version to specref for XEP-0060 The test was originally implemented when version 1.15.7 of the XEP was the most current version. Later versions of the XEP do not significantly modify the specifications (with regards to the functionality that is the subject of the tests), making it plausible that this implementation matches the current version of the XEP: 1.26.0. --- .../org/jivesoftware/smackx/pubsub/PubSubIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/pubsub/PubSubIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/pubsub/PubSubIntegrationTest.java index a9f664f43..1b9954a03 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/pubsub/PubSubIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/pubsub/PubSubIntegrationTest.java @@ -37,7 +37,7 @@ import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.jxmpp.jid.DomainBareJid; -@SpecificationReference(document = "XEP-0060") +@SpecificationReference(document = "XEP-0060", version = "1.26.0") public class PubSubIntegrationTest extends AbstractSmackIntegrationTest { private final PubSubManager pubSubManagerOne; From 7d618563f4dd926b7e3bcaea1d37d54ba78ac43b Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Wed, 12 Jun 2024 17:40:46 +0200 Subject: [PATCH 089/150] [sinttest] Add version to specref for XEP-0232 The test was originally implemented after the most current version of the XEP was published, making it plausible that this implementation matches the current version of the XEP: 0.3. --- .../smackx/softwareInfo/SoftwareInfoIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/softwareInfo/SoftwareInfoIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/softwareInfo/SoftwareInfoIntegrationTest.java index 35e5547d5..838dc3074 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/softwareInfo/SoftwareInfoIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/softwareInfo/SoftwareInfoIntegrationTest.java @@ -36,7 +36,7 @@ import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; import org.igniterealtime.smack.inttest.annotations.SpecificationReference; import org.igniterealtime.smack.inttest.util.IntegrationTestRosterUtil; -@SpecificationReference(document = "XEP-0232") +@SpecificationReference(document = "XEP-0232", version = "0.3") public class SoftwareInfoIntegrationTest extends AbstractSmackIntegrationTest { public final SoftwareInfoManager sim1; From fc1e670a0252c5a880c9ae933556e38b45478997 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Wed, 12 Jun 2024 17:42:18 +0200 Subject: [PATCH 090/150] [sinttest] Add version to specref for XEP-0118 The test was originally implemented when version 1.2 of the XEP was the most current version. Later versions of the XEP do not significantly modify the specifications, making it plausible that this implementation matches the current version of the XEP: 1.3.0. --- .../jivesoftware/smackx/usertune/UserTuneIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 6127b80d7..97d6eb971 100644 --- 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 @@ -36,7 +36,7 @@ import org.igniterealtime.smack.inttest.util.IntegrationTestRosterUtil; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; import org.junit.jupiter.api.Assertions; -@SpecificationReference(document = "XEP-0118") +@SpecificationReference(document = "XEP-0118", version = "1.3.0") public class UserTuneIntegrationTest extends AbstractSmackIntegrationTest { private final UserTuneManager utm1; From adafcdb6d1dc6806ec487b7d74ccdc7df15066b4 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 13 Jun 2024 15:26:42 +0200 Subject: [PATCH 091/150] [sinttest] Fix race condition in MUC test When occupant One waits for occupant Two to join the room, One should register the corresponding listener _before_ Two joins. Without this, a race conditions occurs, where Two could have joined the room before One registered the listener, thus missing the event. --- .../smackx/muc/MultiUserChatOccupantIntegrationTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java index 4caad88d9..396097868 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java @@ -214,16 +214,15 @@ public class MultiUserChatOccupantIntegrationTest extends AbstractMultiUserChatI final Resourcepart nicknameThree = Resourcepart.from("three-" + randomString); createMuc(mucAsSeenByOne, nicknameOne); - mucAsSeenByTwo.join(nicknameTwo); - SimpleResultSyncPoint oneSeesTwo = new SimpleResultSyncPoint(); mucAsSeenByOne.addParticipantListener(presence -> { if (nicknameTwo.equals(presence.getFrom().getResourceOrEmpty())) { oneSeesTwo.signal(); } }); - mucAsSeenByOne.grantModerator(nicknameTwo); + mucAsSeenByTwo.join(nicknameTwo); oneSeesTwo.waitForResult(timeout); + mucAsSeenByOne.grantModerator(nicknameTwo); List results = new ArrayList<>(); mucAsSeenByThree.addParticipantListener(results::add); From 440b49763829237fbb966fd723cd71fcf81730ce Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 13 Jun 2024 15:31:18 +0200 Subject: [PATCH 092/150] [sinttest] Add AssertResult for MultiResultSyncPoint This adds an AssertResult implementation for MultiResultSyncPoint that mimics the equivalent for ResultSyncPoint. --- .../smack/inttest/AbstractSmackIntTest.java | 16 ++++++++++++++++ .../smack/inttest/util/MultiResultSyncPoint.java | 8 ++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/AbstractSmackIntTest.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/AbstractSmackIntTest.java index 11334dee8..9f94fe26b 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/AbstractSmackIntTest.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/AbstractSmackIntTest.java @@ -20,6 +20,7 @@ import java.io.File; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; +import java.util.List; import java.util.Random; import java.util.concurrent.TimeoutException; import java.util.logging.Logger; @@ -33,6 +34,7 @@ import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.StanzaFilter; +import org.igniterealtime.smack.inttest.util.MultiResultSyncPoint; import org.igniterealtime.smack.inttest.util.ResultSyncPoint; import org.opentest4j.AssertionFailedError; @@ -108,4 +110,18 @@ public abstract class AbstractSmackIntTest { throw new AssertionFailedError(message, e); } } + + public List assertResult(MultiResultSyncPoint syncPoint, String message) throws InterruptedException, TimeoutException, AssertionFailedError { + return assertResult(syncPoint, timeout, message); + } + + public static List assertResult(MultiResultSyncPoint syncPoint, long timeout, String message) throws InterruptedException, TimeoutException, AssertionFailedError { + try { + return syncPoint.waitForResults(timeout, message); + } catch (InterruptedException | TimeoutException e) { + throw e; + } catch (Exception e) { + throw new AssertionFailedError(message, e); + } + } } diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/MultiResultSyncPoint.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/MultiResultSyncPoint.java index d04de77c1..da220ff69 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/MultiResultSyncPoint.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/MultiResultSyncPoint.java @@ -1,6 +1,6 @@ /** * - * Copyright 2021 Guus der Kinderen + * Copyright 2021-2024 Guus der Kinderen * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,13 +34,17 @@ public class MultiResultSyncPoint { } public synchronized List waitForResults(long timeout) throws E, InterruptedException, TimeoutException { + return waitForResults(timeout, null); + } + + public synchronized List waitForResults(long timeout, String timeoutMessage) throws E, InterruptedException, TimeoutException { long now = System.currentTimeMillis(); final long deadline = now + timeout; while (results.size() < expectedResultCount && exception == null && now < deadline) { wait(deadline - now); now = System.currentTimeMillis(); } - if (now >= deadline) throw new TimeoutException("MultiResultSyncPoint timeout waiting " + timeout + " millis. Got " + results.size() + " results of " + expectedResultCount + " results"); + if (now >= deadline) throw new TimeoutException((timeoutMessage != null ? timeoutMessage + " " : "") + "MultiResultSyncPoint timeout waiting " + timeout + " millis. Got " + results.size() + " results of " + expectedResultCount + " results"); if (exception != null) throw exception; return new ArrayList<>(results); } From 7e9a5713e96812dc64ba2555fdf79646bb15f707 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 13 Jun 2024 15:32:23 +0200 Subject: [PATCH 093/150] [sinttest] Improve test assertion message Making use of the new assertion handling for MultiResultSyncPoint, the integration test that uses that implementation can now get improved assertion messages. This will allow users to more quickly determine why a test is failing. --- .../smackx/muc/MultiUserChatOccupantIntegrationTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java index 4caad88d9..3be33ae6d 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java @@ -293,10 +293,10 @@ public class MultiUserChatOccupantIntegrationTest extends AbstractMultiUserChatI try { mucAsSeenByThree.join(nicknameThree); - List results = syncPoint.waitForResults(timeout); + List results = assertResult(syncPoint, "Expected all occupants of room '" + mucAddress + "' to be notified of '" + conThree.getUser() + "' using nickname '" + nicknameThree + "' joining the room (but one or more did not get notified)."); assertTrue(results.stream().allMatch( result -> JidCreate.fullFrom(mucAddress, nicknameThree).equals(result.getFrom())), - "Expected all occupants of room '" + mucAddress + "' to be notified of '" + conThree.getUser() + "' using nickname '" + nicknameThree + "' joining the room (but one or more got notified )."); + "Expected all occupants of room '" + mucAddress + "' to be notified of '" + conThree.getUser() + "' using nickname '" + nicknameThree + "' joining the room (but one or more got notified for a different user)."); assertTrue(results.stream().anyMatch( result -> result.getTo().equals(conOne.getUser().asEntityFullJidIfPossible())), "Expected '" + conOne.getUser().asEntityFullJidIfPossible() + "' to be notified of '" + conThree.getUser() + "' joining room '" + mucAddress + "' (but did not)"); From 95c39d2a44de21e0da25743cfac1cf9658da31f3 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Tue, 18 Jun 2024 16:29:57 +0200 Subject: [PATCH 094/150] [docs] fix URL for XEP-0372 --- .../src/main/java/org/jivesoftware/smackx/package-info.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-java8-full/src/main/java/org/jivesoftware/smackx/package-info.java b/smack-java8-full/src/main/java/org/jivesoftware/smackx/package-info.java index d9f01636e..f499a6996 100644 --- a/smack-java8-full/src/main/java/org/jivesoftware/smackx/package-info.java +++ b/smack-java8-full/src/main/java/org/jivesoftware/smackx/package-info.java @@ -511,7 +511,7 @@ * * * References - * XEP-0372 + * XEP-0372 * * Add references like mentions or external data to stanzas. * From 0bb3bf292c051181fae272e1a0b5b97f3dc5dbaa Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 22 Jun 2024 20:01:19 +0200 Subject: [PATCH 095/150] [core] Add NotFilter.of(Class) --- .../java/org/jivesoftware/smack/filter/NotFilter.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/NotFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/NotFilter.java index 006b5f4f9..5589b2109 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/NotFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/NotFilter.java @@ -1,6 +1,6 @@ /** * - * Copyright 2003-2007 Jive Software. + * Copyright 2003-2007 Jive Software, 2024 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.jivesoftware.smack.filter; +import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.util.Objects; @@ -43,4 +44,9 @@ public class NotFilter implements StanzaFilter { public boolean accept(Stanza packet) { return !filter.accept(packet); } + + public static NotFilter of(Class extensionElementClass) { + ExtensionElementFilter extensionElementFilter = new ExtensionElementFilter<>(extensionElementClass); + return new NotFilter(extensionElementFilter); + } } From 98dbc0ee2eb1e15ae83c7ed9025a9b3075670bb1 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Fri, 14 Jun 2024 22:25:05 +0200 Subject: [PATCH 096/150] [muc] Prevent duplicate processing of mediated invitations MUC mediated invitations usually have the form Hey Hecate, this is the place for all good witches! cauldronburn (source: XEP-0045 Example 57.) However, previous versions of XEP-0045 specified an additional element to be included (see implementation note in XEP-0045). Therefore, a legacy implementation may emit a mediated invitations in the form of Unfortunately, this matches MultiUserChatManager.DIRECT_INVITATION_FILTER because GroupChatInvitation matches . However the message is not a direct invitation but a mediated one. Besides this invoking the wrong listeners (direct vs. medidated) the value for 'inviter' that's used to invoke that listener will be false. To fix this, extend DIRECT_INVITATION_FILTER with NotFilter.of(MUCUser.class) to avoid matching those legacy mediated invitations. Fixes SMACK-943 Co-authored-by: Florian Schmaus --- .../java/org/jivesoftware/smackx/muc/MultiUserChatManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java index 47de2163d..9d031a8bd 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java @@ -148,6 +148,7 @@ public final class MultiUserChatManager extends Manager { private static final StanzaFilter DIRECT_INVITATION_FILTER = new AndFilter(StanzaTypeFilter.MESSAGE, new ExtensionElementFilter(GroupChatInvitation.class), + NotFilter.of(MUCUser.class), new NotFilter(MessageTypeFilter.ERROR)); private static final ExpirationCache KNOWN_MUC_SERVICES = new ExpirationCache<>( From 9254f735c79a047626c6579cd9b5ede82be202d2 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 27 Jun 2024 16:49:23 +0200 Subject: [PATCH 097/150] [sinttest] Refactor MultiResulitSyncPoint TimeoutException message construction for readability --- .../smack/inttest/util/MultiResultSyncPoint.java | 10 +++++++++- .../muc/MultiUserChatOccupantIntegrationTest.java | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/MultiResultSyncPoint.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/MultiResultSyncPoint.java index da220ff69..aaf0bd4f1 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/MultiResultSyncPoint.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/MultiResultSyncPoint.java @@ -44,7 +44,15 @@ public class MultiResultSyncPoint { wait(deadline - now); now = System.currentTimeMillis(); } - if (now >= deadline) throw new TimeoutException((timeoutMessage != null ? timeoutMessage + " " : "") + "MultiResultSyncPoint timeout waiting " + timeout + " millis. Got " + results.size() + " results of " + expectedResultCount + " results"); + if (now >= deadline) { + StringBuilder sb = new StringBuilder(); + if (timeoutMessage != null) { + sb.append(timeoutMessage).append(". "); + } + sb.append("MultiResultSyncPoint timeout waiting " + timeout + " ms. Got " + results.size() + " results of " + expectedResultCount + " results"); + + throw new TimeoutException(sb.toString()); + } if (exception != null) throw exception; return new ArrayList<>(results); } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java index 33ed0a816..35721e0b3 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java @@ -292,7 +292,7 @@ public class MultiUserChatOccupantIntegrationTest extends AbstractMultiUserChatI try { mucAsSeenByThree.join(nicknameThree); - List results = assertResult(syncPoint, "Expected all occupants of room '" + mucAddress + "' to be notified of '" + conThree.getUser() + "' using nickname '" + nicknameThree + "' joining the room (but one or more did not get notified)."); + List results = assertResult(syncPoint, "Expected all occupants of room '" + mucAddress + "' to be notified of '" + conThree.getUser() + "' using nickname '" + nicknameThree + "' joining the room (but one or more did not get notified)"); assertTrue(results.stream().allMatch( result -> JidCreate.fullFrom(mucAddress, nicknameThree).equals(result.getFrom())), "Expected all occupants of room '" + mucAddress + "' to be notified of '" + conThree.getUser() + "' using nickname '" + nicknameThree + "' joining the room (but one or more got notified for a different user)."); From 95adfb3cdf8d2d85f10d91dd0399e7f13072130e Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Tue, 25 Jun 2024 17:14:24 +0200 Subject: [PATCH 098/150] [caps] Ensure dataforms are ordered prior to ver calculation Fixes SMACK-944. --- .../smackx/caps/EntityCapsManager.java | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java index 9b736f6d4..15c941ba7 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java @@ -23,6 +23,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Locale; @@ -69,6 +70,7 @@ import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity; import org.jivesoftware.smackx.disco.packet.DiscoverInfoBuilder; import org.jivesoftware.smackx.disco.packet.DiscoverInfoView; import org.jivesoftware.smackx.xdata.FormField; +import org.jivesoftware.smackx.xdata.TextSingleFormField; import org.jivesoftware.smackx.xdata.packet.DataForm; import org.jxmpp.jid.DomainBareJid; @@ -667,16 +669,30 @@ public final class EntityCapsManager extends Manager { } List extendedInfos = discoverInfo.getExtensions(DataForm.class); - for (DataForm extendedInfo : extendedInfos) { - if (!extendedInfo.hasHiddenFormTypeField()) { + final Iterator iter = extendedInfos.iterator(); + while (iter.hasNext()) { + if (!iter.next().hasHiddenFormTypeField()) { // Only use the data form for calculation is it has a hidden FORM_TYPE field. // See XEP-0115 5.4 step 3.f - continue; + iter.remove(); } + } - // 6. If the service discovery information response includes - // XEP-0128 data forms, sort the forms by the FORM_TYPE (i.e., - // by the XML character data of the element). + // 6. If the service discovery information response includes + // XEP-0128 data forms, sort the forms by the FORM_TYPE (i.e., + // by the XML character data of the element). + Collections.sort(extendedInfos, new Comparator() { + @Override + public int compare(DataForm d1, DataForm d2) { + final TextSingleFormField hft1 = d1.getHiddenFormTypeField(); + assert hft1 != null; // ensured by the previous step. + final TextSingleFormField hft2 = d2.getHiddenFormTypeField(); + assert hft2 != null; // ensured by the previous step. + return hft1.getFirstValue().compareTo(hft2.getFirstValue()); + } + }); + + for (DataForm extendedInfo : extendedInfos) { SortedSet fs = new TreeSet<>(new Comparator() { @Override public int compare(FormField f1, FormField f2) { From a1e85d644f188325251dc42d6b40247b64815d53 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Tue, 25 Jun 2024 16:43:48 +0200 Subject: [PATCH 099/150] [caps] Additional test that asserts CAPS dataform ordering XEP-0115 defines that any dataforms in the disco#info stanza is ordered prior to the computation of the verification string. This commit adds a test that verifies that this is done by Smack. See SMACK-944. --- .../smackx/caps/EntityCapsManagerTest.java | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/caps/EntityCapsManagerTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/caps/EntityCapsManagerTest.java index 87700708e..94f0fdaaa 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/caps/EntityCapsManagerTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/caps/EntityCapsManagerTest.java @@ -47,6 +47,41 @@ import org.jxmpp.stringprep.XmppStringprepException; public class EntityCapsManagerTest extends SmackTestSuite { + /** + * XEP- + * 0115 Simple Generation Example. + * @throws XmppStringprepException if the provided string is invalid. + */ + @Test + public void testSimpleGenerationExample() throws XmppStringprepException { + DiscoverInfo di = createSimpleSamplePacket(); + + CapsVersionAndHash versionAndHash = EntityCapsManager.generateVerificationString(di, StringUtils.SHA1); + assertEquals("QgayPKawpkPSDYmwT/WM94uAlu0=", versionAndHash.version); + } + + /** + * Asserts that the order in which data forms are present in the disco/info does not affect the calculated + * verification string, as the XEP mandates that these are ordered by FORM_TYPE (i.e., by the XML character data of + * the element). + * @throws XmppStringprepException if the provided string is invalid. + */ + @Test + public void testReversedDataFormOrder() throws XmppStringprepException { + final DiscoverInfoBuilder builderA = createSimpleSampleBuilder(); + builderA.addExtension(createSampleServerInfoDataForm()); // This works, as the underlying MultiMap maintains insertion-order. + builderA.addExtension(createSampleSoftwareInfoDataForm()); + + final DiscoverInfoBuilder builderB = createSimpleSampleBuilder(); + builderB.addExtension(createSampleSoftwareInfoDataForm()); + builderB.addExtension(createSampleServerInfoDataForm()); + + CapsVersionAndHash versionAndHashA = EntityCapsManager.generateVerificationString(builderA.build(), StringUtils.SHA1); + CapsVersionAndHash versionAndHashB = EntityCapsManager.generateVerificationString(builderB.build(), StringUtils.SHA1); + + assertEquals(versionAndHashA.version, versionAndHashB.version); + } + /** * XEP- * 0115 Complex Generation Example. @@ -142,6 +177,41 @@ public class EntityCapsManagerTest extends SmackTestSuite { return df.build(); } + private static DataForm createSampleServerInfoDataForm() { + DataForm.Builder df = DataForm.builder(DataForm.Type.result); + + { + TextMultiFormField.Builder ff = FormField.textMultiBuilder("admin-addresses"); + ff.addValue("xmpp:admin@example.org"); + ff.addValue("mailto:admin@example.com"); + df.addField(ff.build()); + } + + { + TextSingleFormField.Builder ff = FormField.hiddenBuilder("FORM_TYPE"); + ff.setValue("http://jabber.org/network/serverinfo"); + df.addField(ff.build()); + } + + return df.build(); + } + + private static DiscoverInfoBuilder createSimpleSampleBuilder() throws XmppStringprepException { + DiscoverInfoBuilder di = DiscoverInfo.builder("disco1"); + di.ofType(IQ.Type.result); + + di.addIdentity(new DiscoverInfo.Identity("client", "Exodus 0.9.1", "pc")); + di.addFeature("http://jabber.org/protocol/disco#info"); + di.addFeature("http://jabber.org/protocol/disco#items"); + di.addFeature("http://jabber.org/protocol/muc"); + di.addFeature("http://jabber.org/protocol/caps"); + + return di; + } + private static DiscoverInfo createSimpleSamplePacket() throws XmppStringprepException { + return createSimpleSampleBuilder().build(); + } + private static DiscoverInfo createComplexSamplePacket() throws XmppStringprepException { DiscoverInfoBuilder di = DiscoverInfo.builder("disco1"); di.from(JidCreate.from("benvolio@capulet.lit/230193")); From ba02a868f60d7b58224e190baf7654ef87251df3 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 27 Jun 2024 17:04:05 +0200 Subject: [PATCH 100/150] [caps] Use DataForm.getFormType() when sorting --- .../jivesoftware/smackx/caps/EntityCapsManager.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java index 15c941ba7..32c1af456 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java @@ -70,7 +70,6 @@ import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity; import org.jivesoftware.smackx.disco.packet.DiscoverInfoBuilder; import org.jivesoftware.smackx.disco.packet.DiscoverInfoView; import org.jivesoftware.smackx.xdata.FormField; -import org.jivesoftware.smackx.xdata.TextSingleFormField; import org.jivesoftware.smackx.xdata.packet.DataForm; import org.jxmpp.jid.DomainBareJid; @@ -683,12 +682,12 @@ public final class EntityCapsManager extends Manager { // by the XML character data of the element). Collections.sort(extendedInfos, new Comparator() { @Override - public int compare(DataForm d1, DataForm d2) { - final TextSingleFormField hft1 = d1.getHiddenFormTypeField(); - assert hft1 != null; // ensured by the previous step. - final TextSingleFormField hft2 = d2.getHiddenFormTypeField(); - assert hft2 != null; // ensured by the previous step. - return hft1.getFirstValue().compareTo(hft2.getFirstValue()); + public int compare(DataForm dataFormLeft, DataForm dataFormRight) { + final String formTypeLeft = dataFormLeft.getFormType(); + assert formTypeLeft != null; // ensured by the previous step. + final String formTypeRight = dataFormRight.getFormType(); + assert formTypeRight != null; // ensured by the previous step. + return formTypeLeft.compareTo(formTypeRight); } }); From 0c9d521084fe63ea4bd38d53efeb9a43ac128c82 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Fri, 14 Jun 2024 21:06:43 +0200 Subject: [PATCH 101/150] [sint] Refactor test to ensure stanza order The test that's modified in this commit asserts that upon MUC join, stanzas are received in a particular order. The previous implementation depended on several event listeners (one for presence, one for messages) that did not always fire in the same order in which the corresponding stanzas arrived. This made the approach unsuitable to reliably test the order in which stanzas arrive. This commit stops using Smack's MUC API when trying to collect the order in which stanzas arrive. Instead, it joins a chatroom and listens for its stanzas using basic stanza handling. As this uses exactly one stanza listener, that's guaranteed to be invoked in order of stanza arrival, any synchronicity issue in the previous implementation no longer applies. --- .../MultiUserChatOccupantIntegrationTest.java | 50 ++++++++----------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java index 4caad88d9..cb31b567b 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java @@ -33,8 +33,10 @@ import java.util.stream.Collectors; import org.jivesoftware.smack.PresenceListener; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.filter.FromMatchesFilter; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Presence; +import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.StanzaError; import org.jivesoftware.smack.sm.predicates.ForEveryMessage; import org.jivesoftware.smack.util.StringUtils; @@ -51,7 +53,6 @@ import org.igniterealtime.smack.inttest.util.MultiResultSyncPoint; import org.igniterealtime.smack.inttest.util.ResultSyncPoint; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; import org.jxmpp.jid.EntityBareJid; -import org.jxmpp.jid.EntityFullJid; import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.parts.Resourcepart; @@ -73,6 +74,10 @@ public class MultiUserChatOccupantIntegrationTest extends AbstractMultiUserChatI "§ 7.1 The order of events involved in joining a room needs to be consistent so that clients can know which events to expect when. After a client sends presence to join a room, the MUC service MUST send it events in the following order: 1. In-room presence from other occupants 2. In-room presence from the joining entity itself (so-called \"self-presence\") 3. Room history (if any) 4. The room subject [...]" + "§ 7.2.2 This self-presence MUST NOT be sent to the new occupant until the room has sent the presence of all other occupants to the new occupant ... The service MUST first send the complete list of the existing occupants to the new occupant and only then send the new occupant's own presence to the new occupant") public void mucJoinEventOrderingTest() throws Exception { + // This implementation deliberately does not use Smack's MUC API when trying to collect the order in which + // stanzas arrive. Instead, it joins a chatroom and listens for its stanzas using basic stanza handling. As + // this uses exactly one stanza listener, that's guaranteed to be invoked in order of stanza arrival, which is + // not necessarily the case when using the MUC API. EntityBareJid mucAddress = getRandomRoom("smack-inttest-eventordering"); final String mucSubject = "Subject smack-inttest-eventordering " + randomString; final String mucMessage = "Message smack-inttest-eventordering " + randomString; @@ -101,41 +106,28 @@ public class MultiUserChatOccupantIntegrationTest extends AbstractMultiUserChatI messageReflectionSyncPoint.waitForResult(timeout); final ResultSyncPoint subjectResultSyncPoint = new ResultSyncPoint<>(); - List results = new ArrayList<>(); - - mucAsSeenByTwo.addMessageListener(message -> { - String body = message.getBody(); - if (mucMessage.equals(body)) { - results.add(body); + final List results = new ArrayList<>(); + conTwo.addStanzaListener(stanza -> { + results.add(stanza); + if (stanza instanceof Message && ((Message) stanza).getSubject() != null) { + subjectResultSyncPoint.signal(((Message) stanza).getSubject()); } - }); - - mucAsSeenByTwo.addParticipantStatusListener(new ParticipantStatusListener() { - @Override public void joined(EntityFullJid participant) { - // Ignore self-presence, but record all other participants. - final EntityFullJid participantTwo = JidCreate.entityFullFrom(mucAddress, nicknameTwo); - if (!participantTwo.equals(participant)) { - results.add(participant); - } - } - }); - - mucAsSeenByTwo.addSubjectUpdatedListener((subject, from) -> { - results.add(subject); - subjectResultSyncPoint.signal(subject); - }); + }, FromMatchesFilter.create(mucAddress)); try { - Presence reflectedJoinPresence = mucAsSeenByTwo.join(nicknameTwo); - results.add(reflectedJoinPresence.getFrom()); // Self-presence should be second + mucAsSeenByTwo.join(nicknameTwo); subjectResultSyncPoint.waitForResult(timeout); // Wait for subject, as it should be 4th (last) assertEquals(4, results.size(), "Unexpected amount of stanzas received by '" + conTwo.getUser() + "' after it joined room '" + mucAddress + "'."); - assertEquals(JidCreate.fullFrom(mucAddress, nicknameOne), results.get(0), "Unexpected 'from' address of the first stanza that was received by '" + conTwo.getUser() + "' after it joined room '" + mucAddress + "'."); - assertEquals(JidCreate.fullFrom(mucAddress, nicknameTwo), results.get(1), "Unexpected 'from' address of the seconds stanza that was received by '" + conTwo.getUser() + "' after it joined room '" + mucAddress + "'."); - assertEquals(mucMessage, results.get(2), "The third stanza that was received by '" + conTwo.getUser() + "' after it joined room '" + mucAddress + "' was expected to be a different stanza."); - assertEquals(mucSubject, results.get(3), "The fourth stanza that was received by '" + conTwo.getUser() + "' after it joined room '" + mucAddress + "' was expected to be a different stanza."); + assertTrue(results.get(0) instanceof Presence, "Expected the first stanza that was received by '" + conTwo.getUser() + "' after it joined room '" + mucAddress + "' to be a presence stanza (but it was not)."); + assertEquals(JidCreate.fullFrom(mucAddress, nicknameOne), results.get(0).getFrom(), "Unexpected 'from' address of the first stanza that was received by '" + conTwo.getUser() + "' after it joined room '" + mucAddress + "'."); + assertTrue(results.get(1) instanceof Presence, "Expected the second stanza that was received by '" + conTwo.getUser() + "' after it joined room '" + mucAddress + "' to be a presence stanza (but it was not)."); + assertEquals(JidCreate.fullFrom(mucAddress, nicknameTwo), results.get(1).getFrom(), "Unexpected 'from' address of the seconds stanza that was received by '" + conTwo.getUser() + "' after it joined room '" + mucAddress + "'."); + assertTrue(results.get(2) instanceof Message, "Expected the third stanza that was received by '" + conTwo.getUser() + "' after it joined room '" + mucAddress + "' to be a message stanza (but it was not)."); + assertEquals(mucMessage, ((Message) results.get(2)).getBody(), "The third stanza that was received by '" + conTwo.getUser() + "' after it joined room '" + mucAddress + "' was expected to be a different stanza."); + assertTrue(results.get(3) instanceof Message, "Expected the fourth stanza that was received by '" + conTwo.getUser() + "' after it joined room '" + mucAddress + "' to be a message stanza (but it was not)."); + assertEquals(mucSubject, ((Message) results.get(3)).getSubject(), "The fourth stanza that was received by '" + conTwo.getUser() + "' after it joined room '" + mucAddress + "' was expected to be a different stanza."); } finally { tryDestroy(mucAsSeenByOne); } From d27fef0baefe03f3543f51ccf748902260814a29 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 27 Jun 2024 21:29:33 +0200 Subject: [PATCH 102/150] [sinttest] Do not leak stanza listener in MultiUserChatOccupantIntegrationTest --- .../smackx/muc/MultiUserChatOccupantIntegrationTest.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java index b8883dd05..c662ef3f1 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java @@ -32,6 +32,7 @@ import java.util.stream.Collectors; import org.jivesoftware.smack.PresenceListener; import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.StanzaListener; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.filter.FromMatchesFilter; import org.jivesoftware.smack.packet.Message; @@ -107,12 +108,13 @@ public class MultiUserChatOccupantIntegrationTest extends AbstractMultiUserChatI final ResultSyncPoint subjectResultSyncPoint = new ResultSyncPoint<>(); final List results = new ArrayList<>(); - conTwo.addStanzaListener(stanza -> { + final StanzaListener stanzaListener = stanza -> { results.add(stanza); if (stanza instanceof Message && ((Message) stanza).getSubject() != null) { subjectResultSyncPoint.signal(((Message) stanza).getSubject()); } - }, FromMatchesFilter.create(mucAddress)); + }; + conTwo.addStanzaListener(stanzaListener, FromMatchesFilter.create(mucAddress)); try { mucAsSeenByTwo.join(nicknameTwo); @@ -130,6 +132,7 @@ public class MultiUserChatOccupantIntegrationTest extends AbstractMultiUserChatI assertEquals(mucSubject, ((Message) results.get(3)).getSubject(), "The fourth stanza that was received by '" + conTwo.getUser() + "' after it joined room '" + mucAddress + "' was expected to be a different stanza."); } finally { tryDestroy(mucAsSeenByOne); + conTwo.removeStanzaListener(stanzaListener); } } From 426a5efb1de171edac1cbd94764db9edd2484963 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Tue, 2 Jul 2024 10:50:42 +0200 Subject: [PATCH 103/150] [sinttest] Cleanup of test fixtures Additional cleanup of test fixtures: - various tests that change roster/subscription get a roster-reset - one test that registers a listener now deregisters that listener --- .../roster/LowLevelRosterIntegrationTest.java | 25 +++++++++++++------ .../GeolocationIntegrationTest.java | 2 ++ .../smackx/mood/MoodIntegrationTest.java | 2 ++ .../SoftwareInfoIntegrationTest.java | 6 +++++ .../usertune/UserTuneIntegrationTest.java | 2 ++ 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/LowLevelRosterIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/LowLevelRosterIntegrationTest.java index 305e9ae47..045f06691 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/LowLevelRosterIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/LowLevelRosterIntegrationTest.java @@ -49,7 +49,7 @@ public class LowLevelRosterIntegrationTest extends AbstractSmackLowLevelIntegrat final SimpleResultSyncPoint offlineTriggered = new SimpleResultSyncPoint(); - rosterOne.addPresenceEventListener(new AbstractPresenceEventListener() { + final AbstractPresenceEventListener presenceEventListener = new AbstractPresenceEventListener() { @Override public void presenceUnavailable(FullJid jid, Presence presence) { if (!jid.equals(conTwo.getUser())) { @@ -57,15 +57,24 @@ public class LowLevelRosterIntegrationTest extends AbstractSmackLowLevelIntegrat } offlineTriggered.signal(); } - }); + }; + rosterOne.addPresenceEventListener(presenceEventListener); - // Disconnect conTwo, this should cause an 'unavailable' presence to be send from conTwo to - // conOne. - conTwo.disconnect(); + try { + // Disconnect conTwo, this should cause an 'unavailable' presence to be send from conTwo to + // conOne. + conTwo.disconnect(); - Boolean result = offlineTriggered.waitForResult(timeout); - if (!result) { - throw new Exception("presenceUnavailable() was not called"); + Boolean result = offlineTriggered.waitForResult(timeout); + if (!result) { + throw new Exception("presenceUnavailable() was not called"); + } + } finally { + // Clean up test fixture. + rosterOne.removePresenceEventListener(presenceEventListener); + conTwo.connect(); + conTwo.login(); + IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); } } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/geolocation/GeolocationIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/geolocation/GeolocationIntegrationTest.java index f7e708775..1cd1d3b8d 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/geolocation/GeolocationIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/geolocation/GeolocationIntegrationTest.java @@ -111,6 +111,7 @@ public class GeolocationIntegrationTest extends AbstractSmackIntegrationTest { " that contained '" + data.toXML() + "', but did not."); } finally { unregisterListener(glm2, geoLocationListener); + IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); } } @@ -171,6 +172,7 @@ public class GeolocationIntegrationTest extends AbstractSmackIntegrationTest { " that contained '" + data.toXML() + "', but did not."); } finally { unregisterListener(glm2, geoLocationListener); + IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); } } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/mood/MoodIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/mood/MoodIntegrationTest.java index 9b1dfeacd..c430938db 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/mood/MoodIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/mood/MoodIntegrationTest.java @@ -82,6 +82,7 @@ public class MoodIntegrationTest extends AbstractSmackIntegrationTest { assertResult(moodReceived, "Expected " + conTwo.getUser() + " to receive a PEP notification, but did not."); } finally { unregisterListener(mm2, moodListener); + IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); } } @@ -117,6 +118,7 @@ public class MoodIntegrationTest extends AbstractSmackIntegrationTest { assertResult(moodReceived, "Expected " + conTwo.getUser() + " to receive a PEP notification, but did not."); } finally { unregisterListener(mm2, moodListener); + IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); } } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/softwareInfo/SoftwareInfoIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/softwareInfo/SoftwareInfoIntegrationTest.java index 838dc3074..f01371f10 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/softwareInfo/SoftwareInfoIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/softwareInfo/SoftwareInfoIntegrationTest.java @@ -31,6 +31,7 @@ import org.jivesoftware.smackx.softwareinfo.form.SoftwareInfoForm; import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; +import org.igniterealtime.smack.inttest.annotations.AfterClass; import org.igniterealtime.smack.inttest.annotations.BeforeClass; import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; import org.igniterealtime.smack.inttest.annotations.SpecificationReference; @@ -54,6 +55,11 @@ public class SoftwareInfoIntegrationTest extends AbstractSmackIntegrationTest { IntegrationTestRosterUtil.ensureBothAccountsAreSubscribedToEachOther(conOne, conTwo, timeout); } + @AfterClass + public void cleanUp() throws Exception { + IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); + } + @SmackIntegrationTest public void test() throws Exception { SoftwareInfoForm softwareInfoSent = createSoftwareInfoForm(); 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 index 97d6eb971..e204031c4 100644 --- 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 @@ -98,6 +98,7 @@ public class UserTuneIntegrationTest extends AbstractSmackIntegrationTest { Assertions.assertNotNull(result, "Expected to receive a PEP notification, but did not."); } finally { unregisterListener(utm2, userTuneListener); + IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); } } @@ -142,6 +143,7 @@ public class UserTuneIntegrationTest extends AbstractSmackIntegrationTest { assertResult(userTuneReceived, "Expected " + conTwo.getUser() + " to receive a PEP notification from " + conOne.getUser() + ", but did not."); } finally { unregisterListener(utm2, userTuneListener); + IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); } } From 59706d0294ba1d4cebe081c0edd59c6e8aec2289 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Wed, 3 Jul 2024 16:11:27 +0200 Subject: [PATCH 104/150] [sinttest] XEP-0373 Integration Tests should clean-up After test execution, the OpenPGP for XMPP integration tests should clean up the data published via PEP. This prevents these tests from interfering with other tests. --- .../ox/OXSecretKeyBackupIntegrationTest.java | 48 +++++++++++-------- .../OXInstantMessagingIntegrationTest.java | 34 ++++++++----- 2 files changed, 48 insertions(+), 34 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/OXSecretKeyBackupIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/OXSecretKeyBackupIntegrationTest.java index 0aa708e9f..93f936785 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/OXSecretKeyBackupIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/OXSecretKeyBackupIntegrationTest.java @@ -38,6 +38,7 @@ import org.jivesoftware.smackx.ox.exception.MissingUserIdOnKeyException; import org.jivesoftware.smackx.ox.exception.NoBackupFoundException; import org.jivesoftware.smackx.ox.store.definition.OpenPgpStore; import org.jivesoftware.smackx.ox.store.filebased.FileBasedOpenPgpStore; +import org.jivesoftware.smackx.ox.util.OpenPgpPubSubUtil; import org.jivesoftware.smackx.pubsub.PubSubException; import org.bouncycastle.openpgp.PGPException; @@ -122,38 +123,43 @@ public class OXSecretKeyBackupIntegrationTest extends AbstractOpenPgpIntegration assertNull(self.getSigningKeyFingerprint()); OpenPgpV4Fingerprint keyFingerprint = openPgpManager.generateAndImportKeyPair(alice); - assertEquals(keyFingerprint, self.getSigningKeyFingerprint()); - assertTrue(self.getSecretKeys().contains(keyFingerprint.getKeyId())); + try { + assertEquals(keyFingerprint, self.getSigningKeyFingerprint()); + assertTrue(self.getSecretKeys().contains(keyFingerprint.getKeyId())); - PGPSecretKeyRing beforeSec = beforeStore.getSecretKeyRing(alice, keyFingerprint); - assertNotNull(beforeSec); + PGPSecretKeyRing beforeSec = beforeStore.getSecretKeyRing(alice, keyFingerprint); + assertNotNull(beforeSec); - PGPPublicKeyRing beforePub = beforeStore.getPublicKeyRing(alice, keyFingerprint); - assertNotNull(beforePub); + PGPPublicKeyRing beforePub = beforeStore.getPublicKeyRing(alice, keyFingerprint); + assertNotNull(beforePub); - OpenPgpSecretKeyBackupPassphrase backupPassphrase = + OpenPgpSecretKeyBackupPassphrase backupPassphrase = openPgpManager.backupSecretKeyToServer(availableSecretKeys -> availableSecretKeys); - FileBasedOpenPgpStore afterStore = new FileBasedOpenPgpStore(afterPath); - afterStore.setKeyRingProtector(new UnprotectedKeysProtector()); - PainlessOpenPgpProvider afterProvider = new PainlessOpenPgpProvider(afterStore); - openPgpManager.setOpenPgpProvider(afterProvider); + FileBasedOpenPgpStore afterStore = new FileBasedOpenPgpStore(afterPath); + afterStore.setKeyRingProtector(new UnprotectedKeysProtector()); + PainlessOpenPgpProvider afterProvider = new PainlessOpenPgpProvider(afterStore); + openPgpManager.setOpenPgpProvider(afterProvider); - OpenPgpV4Fingerprint fingerprint = openPgpManager.restoreSecretKeyServerBackup(() -> backupPassphrase); + OpenPgpV4Fingerprint fingerprint = openPgpManager.restoreSecretKeyServerBackup(() -> backupPassphrase); - assertEquals(keyFingerprint, fingerprint); + assertEquals(keyFingerprint, fingerprint); - assertTrue(self.getSecretKeys().contains(keyFingerprint.getKeyId())); + assertTrue(self.getSecretKeys().contains(keyFingerprint.getKeyId())); - assertEquals(keyFingerprint, self.getSigningKeyFingerprint()); + assertEquals(keyFingerprint, self.getSigningKeyFingerprint()); - PGPSecretKeyRing afterSec = afterStore.getSecretKeyRing(alice, keyFingerprint); - assertNotNull(afterSec); - assertArrayEquals(beforeSec.getEncoded(), afterSec.getEncoded()); + PGPSecretKeyRing afterSec = afterStore.getSecretKeyRing(alice, keyFingerprint); + assertNotNull(afterSec); + assertArrayEquals(beforeSec.getEncoded(), afterSec.getEncoded()); - PGPPublicKeyRing afterPub = afterStore.getPublicKeyRing(alice, keyFingerprint); - assertNotNull(afterPub); - assertArrayEquals(beforePub.getEncoded(), afterPub.getEncoded()); + PGPPublicKeyRing afterPub = afterStore.getPublicKeyRing(alice, keyFingerprint); + assertNotNull(afterPub); + assertArrayEquals(beforePub.getEncoded(), afterPub.getEncoded()); + } finally { + OpenPgpPubSubUtil.deletePublicKeyNode(alicePepManager, keyFingerprint); + OpenPgpPubSubUtil.deletePubkeysListNode(alicePepManager); + } } } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingIntegrationTest.java index 0dc597853..4467dde1f 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingIntegrationTest.java @@ -33,6 +33,7 @@ import org.jivesoftware.smackx.ox.OpenPgpManager; import org.jivesoftware.smackx.ox.crypto.PainlessOpenPgpProvider; import org.jivesoftware.smackx.ox.element.SigncryptElement; import org.jivesoftware.smackx.ox.store.filebased.FileBasedOpenPgpStore; +import org.jivesoftware.smackx.ox.util.OpenPgpPubSubUtil; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.TestNotPossibleException; @@ -139,26 +140,33 @@ public class OXInstantMessagingIntegrationTest extends AbstractOpenPgpIntegratio aliceFingerprint = aliceOpenPgp.generateAndImportKeyPair(alice); bobFingerprint = bobOpenPgp.generateAndImportKeyPair(bob); - aliceOpenPgp.announceSupportAndPublish(); - bobOpenPgp.announceSupportAndPublish(); + try { + aliceOpenPgp.announceSupportAndPublish(); + bobOpenPgp.announceSupportAndPublish(); - OpenPgpContact bobForAlice = aliceOpenPgp.getOpenPgpContact(bob.asEntityBareJidIfPossible()); - OpenPgpContact aliceForBob = bobOpenPgp.getOpenPgpContact(alice.asEntityBareJidIfPossible()); + OpenPgpContact bobForAlice = aliceOpenPgp.getOpenPgpContact(bob.asEntityBareJidIfPossible()); + OpenPgpContact aliceForBob = bobOpenPgp.getOpenPgpContact(alice.asEntityBareJidIfPossible()); - bobForAlice.updateKeys(aliceConnection); + bobForAlice.updateKeys(aliceConnection); - assertFalse(bobForAlice.isTrusted(bobFingerprint)); - assertFalse(aliceForBob.isTrusted(aliceFingerprint)); + assertFalse(bobForAlice.isTrusted(bobFingerprint)); + assertFalse(aliceForBob.isTrusted(aliceFingerprint)); - bobForAlice.trust(bobFingerprint); - aliceForBob.trust(aliceFingerprint); + bobForAlice.trust(bobFingerprint); + aliceForBob.trust(aliceFingerprint); - assertTrue(bobForAlice.isTrusted(bobFingerprint)); - assertTrue(aliceForBob.isTrusted(aliceFingerprint)); + assertTrue(bobForAlice.isTrusted(bobFingerprint)); + assertTrue(aliceForBob.isTrusted(aliceFingerprint)); - aliceInstantMessaging.sendOxMessage(bobForAlice, body); + aliceInstantMessaging.sendOxMessage(bobForAlice, body); - bobReceivedMessage.waitForResult(timeout); + bobReceivedMessage.waitForResult(timeout); + } finally { + OpenPgpPubSubUtil.deletePublicKeyNode(alicePepManager, aliceFingerprint); + OpenPgpPubSubUtil.deletePubkeysListNode(alicePepManager); + OpenPgpPubSubUtil.deletePublicKeyNode(bobPepManager, bobFingerprint); + OpenPgpPubSubUtil.deletePubkeysListNode(bobPepManager); + } } } From 7c27a707c8f29b1bb4c8a51838a1af24f59b08e7 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Fri, 5 Jul 2024 15:14:43 +0200 Subject: [PATCH 105/150] [muc] MUC Item actor's nick to XML If an actor's nick is set in `MUCItem` this value should be added to the XMPP representation of the instance. Fixes SMACK-945 --- .../java/org/jivesoftware/smackx/muc/packet/MUCItem.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/MUCItem.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/MUCItem.java index c1ee5ae28..8da0efb78 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/MUCItem.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/MUCItem.java @@ -169,8 +169,11 @@ public class MUCItem implements NamedElement { xml.optAttribute("role", getRole()); xml.rightAngleBracket(); xml.optElement("reason", getReason()); - if (getActor() != null) { - xml.halfOpenElement("actor").attribute("jid", getActor()).closeEmptyElement(); + if (getActor() != null || getActorNick() != null) { + xml.halfOpenElement("actor"); + xml.optAttribute("jid", getActor()); + xml.optAttribute("nick", getActorNick()); + xml.closeEmptyElement(); } xml.closeElement(Stanza.ITEM); return xml; From f0b9955311391750e93dacb31aa809a8e4068941 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Sat, 13 Jul 2024 14:59:07 +0200 Subject: [PATCH 106/150] [muc] Invoke ParticipantStatusListener after revokation of membership When an occupant gets its membership revoked in an members-only room, the appropriate method of registered ParticipantStatusListeners should be invoked. --- .../smackx/muc/MultiUserChat.java | 4 + .../muc/ParticipantStatusIntegrationTest.java | 132 ++++++++++++++++++ .../smackx/muc/UserStatusIntegrationTest.java | 128 +++++++++++++++++ 3 files changed, 264 insertions(+) create mode 100644 smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/ParticipantStatusIntegrationTest.java create mode 100644 smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/UserStatusIntegrationTest.java diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java index 45d474749..1628f258d 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java @@ -2636,6 +2636,10 @@ public class MultiUserChat { for (UserStatusListener listener : userStatusListeners) { listener.membershipRevoked(); } + } else { + for (ParticipantStatusListener listener : participantStatusListeners) { + listener.membershipRevoked(from); + } } } // A occupant has changed his nickname in the room diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/ParticipantStatusIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/ParticipantStatusIntegrationTest.java new file mode 100644 index 000000000..f4ebfdd70 --- /dev/null +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/ParticipantStatusIntegrationTest.java @@ -0,0 +1,132 @@ +/** + * + * Copyright 2024 Guus der Kinderen + * + * 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.muc; + +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.XMPPException; + +import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; +import org.igniterealtime.smack.inttest.TestNotPossibleException; +import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; +import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; +import org.jxmpp.jid.EntityBareJid; +import org.jxmpp.jid.EntityFullJid; +import org.jxmpp.jid.impl.JidCreate; +import org.jxmpp.jid.parts.Resourcepart; + +/** + * Tests that verify the correct functionality of Smack's {@link ParticipantStatusListener}. + */ +@SpecificationReference(document = "XEP-0045", version = "1.34.6") +public class ParticipantStatusIntegrationTest extends AbstractMultiUserChatIntegrationTest { + + public ParticipantStatusIntegrationTest(SmackIntegrationTestEnvironment environment) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, TestNotPossibleException { + super(environment); + } + + /** + * Verifies that when a member gets its membership removed in an open room, the appropriate event listener is invoked. + * + * @throws Exception On unexpected results + */ + @SmackIntegrationTest(section = "9.4", quote = "An admin might want to revoke a user's membership [...] The service MUST then send updated presence from this individual to all occupants, indicating the loss of membership by sending a presence element that contains an element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an child with the 'affiliation' attribute set to a value of \"none\".") + public void testMembershipRevokedInOpenRoom() throws Exception { + // Setup test fixture. + final EntityBareJid mucAddress = getRandomRoom("smack-inttest-participantstatus-membership-revoked-open"); + final MultiUserChat mucAsSeenByOwner = mucManagerOne.getMultiUserChat(mucAddress); + final MultiUserChat mucAsSeenByTarget = mucManagerTwo.getMultiUserChat(mucAddress); + + final EntityFullJid mucAddressOwner = JidCreate.entityFullFrom(mucAddress, Resourcepart.from("owner-" + randomString)); + final EntityFullJid mucAddressTarget = JidCreate.entityFullFrom(mucAddress, Resourcepart.from("target-" + randomString)); + + createMuc(mucAsSeenByOwner, mucAddressOwner.getResourcepart()); + try { + mucAsSeenByOwner.grantMembership(conTwo.getUser().asBareJid()); + mucAsSeenByTarget.join(mucAddressTarget.getResourcepart()); + + final SimpleResultSyncPoint ownerSeesRevoke = new SimpleResultSyncPoint(); + mucAsSeenByOwner.addParticipantStatusListener(new ParticipantStatusListener() { + @Override + public void membershipRevoked(EntityFullJid participant) { + if (mucAddressTarget.equals(participant)) { + ownerSeesRevoke.signal(); + } + } + }); + + // Execute system under test. + mucAsSeenByOwner.revokeMembership(conTwo.getUser().asBareJid()); + + // Verify result. + assertResult(ownerSeesRevoke, "Expected '" + conOne.getUser() + "' to be notified of the revocation of membership of '" + conTwo.getUser() + "' (using nickname '" + mucAddressTarget.getResourcepart() + "') in '" + mucAddress + "' (but did not)."); + } finally { + // Clean up test fixture. + tryDestroy(mucAsSeenByOwner); + } + } + + /** + * Verifies that when a member gets its membership removed in a members-only room, the appropriate event listeners are invoked. + * + * @throws Exception On unexpected results + */ + @SmackIntegrationTest(section = "9.4", quote = "An admin might want to revoke a user's membership [...] If the room is members-only, the service MUST remove the user from the room, including a status code of 321 to indicate that the user was removed because of an affiliation change, and inform all remaining occupants") + public void testMembershipRevokedInMemberOnlyRoom() throws Exception { + // Setup test fixture. + final EntityBareJid mucAddress = getRandomRoom("smack-inttest-participantstatus-membership-revoked-membersonly"); + final MultiUserChat mucAsSeenByOwner = mucManagerOne.getMultiUserChat(mucAddress); + final MultiUserChat mucAsSeenByTarget = mucManagerTwo.getMultiUserChat(mucAddress); + + final EntityFullJid mucAddressOwner = JidCreate.entityFullFrom(mucAddress, Resourcepart.from("owner-" + randomString)); + final EntityFullJid mucAddressTarget = JidCreate.entityFullFrom(mucAddress, Resourcepart.from("target-" + randomString)); + + createMembersOnlyMuc(mucAsSeenByOwner, mucAddressOwner.getResourcepart()); + try { + mucAsSeenByOwner.grantMembership(conTwo.getUser().asBareJid()); + mucAsSeenByTarget.join(mucAddressTarget.getResourcepart()); + + final SimpleResultSyncPoint ownerSeesRevoke = new SimpleResultSyncPoint(); + final SimpleResultSyncPoint ownerSeesDeparture = new SimpleResultSyncPoint(); + mucAsSeenByOwner.addParticipantStatusListener(new ParticipantStatusListener() { + @Override + public void membershipRevoked(EntityFullJid participant) { + if (mucAddressTarget.equals(participant)) { + ownerSeesRevoke.signal(); + } + } + + @Override + public void parted(EntityFullJid participant) { + if (mucAddressTarget.equals(participant)) { + ownerSeesDeparture.signal(); + } + } + }); + + // Execute system under test. + mucAsSeenByOwner.revokeMembership(conTwo.getUser().asBareJid()); + + // Verify result. + assertResult(ownerSeesRevoke, "Expected '" + conOne.getUser() + "' to be notified of the revocation of membership of '" + conTwo.getUser() + "' (using nickname '" + mucAddressTarget.getResourcepart() + "') in '" + mucAddress + "' (but did not)."); + assertResult(ownerSeesDeparture, "Expected '" + conOne.getUser() + "' to be notified of '" + conTwo.getUser() + "' (using nickname '" + mucAddressTarget.getResourcepart() + "') departing '" + mucAddress + "' (but did not)."); + } finally { + // Clean up test fixture. + tryDestroy(mucAsSeenByOwner); + } + } +} diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/UserStatusIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/UserStatusIntegrationTest.java new file mode 100644 index 000000000..3395d4068 --- /dev/null +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/UserStatusIntegrationTest.java @@ -0,0 +1,128 @@ +/** + * + * Copyright 2024 Guus der Kinderen + * + * 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.muc; + +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.packet.Presence; +import org.jivesoftware.smackx.muc.packet.MUCUser; + +import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; +import org.igniterealtime.smack.inttest.TestNotPossibleException; +import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.annotations.SpecificationReference; +import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; +import org.jxmpp.jid.EntityBareJid; +import org.jxmpp.jid.EntityFullJid; +import org.jxmpp.jid.impl.JidCreate; +import org.jxmpp.jid.parts.Resourcepart; + +/** + * Tests that verify the correct functionality of Smack's {@link UserStatusListener}. + */ +@SpecificationReference(document = "XEP-0045", version = "1.34.6") +public class UserStatusIntegrationTest extends AbstractMultiUserChatIntegrationTest { + + public UserStatusIntegrationTest(SmackIntegrationTestEnvironment environment) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, TestNotPossibleException { + super(environment); + } + + /** + * Verifies that when a member gets its membership removed in an open room, the appropriate event listener is invoked. + * + * @throws Exception On unexpected results + */ + @SmackIntegrationTest(section = "9.4", quote = "An admin might want to revoke a user's membership [...] The service MUST then send updated presence from this individual to all occupants, indicating the loss of membership by sending a presence element that contains an element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an child with the 'affiliation' attribute set to a value of \"none\".") + public void testMembershipRevokedInOpenRoom() throws Exception { + // Setup test fixture. + final EntityBareJid mucAddress = getRandomRoom("smack-inttest-userstatus-membership-revoked-membersonly"); + final MultiUserChat mucAsSeenByOwner = mucManagerOne.getMultiUserChat(mucAddress); + final MultiUserChat mucAsSeenByTarget = mucManagerTwo.getMultiUserChat(mucAddress); + + final EntityFullJid mucAddressOwner = JidCreate.entityFullFrom(mucAddress, Resourcepart.from("owner-" + randomString)); + final EntityFullJid mucAddressTarget = JidCreate.entityFullFrom(mucAddress, Resourcepart.from("target-" + randomString)); + + createMuc(mucAsSeenByOwner, mucAddressOwner.getResourcepart()); + try { + mucAsSeenByOwner.grantMembership(conTwo.getUser().asBareJid()); + mucAsSeenByTarget.join(mucAddressTarget.getResourcepart()); + + final SimpleResultSyncPoint targetSeesRevoke = new SimpleResultSyncPoint(); + mucAsSeenByTarget.addUserStatusListener(new UserStatusListener() { + @Override + public void membershipRevoked() { + targetSeesRevoke.signal(); + } + }); + + // Execute system under test. + mucAsSeenByOwner.revokeMembership(conTwo.getUser().asBareJid()); + + // Verify result. + assertResult(targetSeesRevoke, "Expected '" + conTwo.getUser() + "' (using nickname '" + mucAddressTarget.getResourcepart() + "') to be notified that their membership status was removed by '" + conOne.getUser() + "' (using nickname '" + mucAddressOwner.getResourcepart() + "') in '" + mucAddress + "' (but did not)."); + } finally { + // Clean up test fixture. + tryDestroy(mucAsSeenByOwner); + } + } + + /** + * Verifies that when a member gets its membership removed in a members-only room, the appropriate event listeners are invoked. + * + * @throws Exception On unexpected results + */ + @SmackIntegrationTest(section = "9.4", quote = "An admin might want to revoke a user's membership [...] If the room is members-only, the service MUST remove the user from the room, including a status code of 321 to indicate that the user was removed because of an affiliation change, and inform all remaining occupants") + public void testMembershipRevokedInMemberOnlyRoom() throws Exception { + // Setup test fixture. + final EntityBareJid mucAddress = getRandomRoom("smack-inttest-userstatus-membership-revoked-membersonly"); + final MultiUserChat mucAsSeenByOwner = mucManagerOne.getMultiUserChat(mucAddress); + final MultiUserChat mucAsSeenByTarget = mucManagerTwo.getMultiUserChat(mucAddress); + + final EntityFullJid mucAddressOwner = JidCreate.entityFullFrom(mucAddress, Resourcepart.from("owner-" + randomString)); + final EntityFullJid mucAddressTarget = JidCreate.entityFullFrom(mucAddress, Resourcepart.from("target-" + randomString)); + + createMembersOnlyMuc(mucAsSeenByOwner, mucAddressOwner.getResourcepart()); + try { + mucAsSeenByOwner.grantMembership(conTwo.getUser().asBareJid()); + mucAsSeenByTarget.join(mucAddressTarget.getResourcepart()); + + final SimpleResultSyncPoint targetSeesRevoke = new SimpleResultSyncPoint(); + final SimpleResultSyncPoint targetSeesRemove = new SimpleResultSyncPoint(); + mucAsSeenByTarget.addUserStatusListener(new UserStatusListener() { + @Override + public void removed(MUCUser mucUser, Presence presence) { + targetSeesRemove.signal(); + } + + @Override + public void membershipRevoked() { + targetSeesRevoke.signal(); + } + }); + + // Execute system under test. + mucAsSeenByOwner.revokeMembership(conTwo.getUser().asBareJid()); + + // Verify result. + assertResult(targetSeesRemove, "Expected '" + conTwo.getUser() + "' (using nickname '" + mucAddressTarget.getResourcepart() + "') to be notified that it is removed from '" + mucAddress + "' which is a member-only room, as their membership status was removed by '" + conOne.getUser() + "' (using nickname '" + mucAddressOwner.getResourcepart() + "') (but did not)."); + assertResult(targetSeesRevoke, "Expected '" + conTwo.getUser() + "' (using nickname '" + mucAddressTarget.getResourcepart() + "') to be notified that their membership status was removed by '" + conOne.getUser() + "' (using nickname '" + mucAddressOwner.getResourcepart() + "') in '" + mucAddress + "' (but did not)."); + } finally { + // Clean up test fixture. + tryDestroy(mucAsSeenByOwner); + } + } +} From 050acc4c530e70f389e8fd2f6aec858585023ee1 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 14 Jul 2024 12:09:59 +0200 Subject: [PATCH 107/150] [sinttest] Add TestNotPossibleException(String, Throwable) constructor --- .../smack/inttest/TestNotPossibleException.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/TestNotPossibleException.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/TestNotPossibleException.java index 4c09e0f47..cf7030efd 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/TestNotPossibleException.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/TestNotPossibleException.java @@ -30,4 +30,8 @@ public class TestNotPossibleException extends Exception { public TestNotPossibleException(Throwable reason) { super(reason); } + + public TestNotPossibleException(String message, Throwable reason) { + super(message, reason); + } } From 17d9b742fc81398e453f01ff829fff14352add05 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 14 Jul 2024 12:10:34 +0200 Subject: [PATCH 108/150] [sinttest] Try to find MUC service where MUC creation is possible --- .../AbstractMultiUserChatIntegrationTest.java | 42 +++++++++++++++++-- .../MultiUserChatEntityIntegrationTest.java | 6 ++- .../muc/MultiUserChatIntegrationTest.java | 2 +- .../MultiUserChatLowLevelIntegrationTest.java | 10 ++++- .../MultiUserChatOccupantIntegrationTest.java | 6 ++- ...AffiliationsPrivilegesIntegrationTest.java | 8 +++- 6 files changed, 64 insertions(+), 10 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/AbstractMultiUserChatIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/AbstractMultiUserChatIntegrationTest.java index 0f803e97f..b13b4df6e 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/AbstractMultiUserChatIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/AbstractMultiUserChatIntegrationTest.java @@ -18,10 +18,16 @@ package org.jivesoftware.smackx.muc; import java.util.List; +import java.util.logging.Level; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; +import org.jivesoftware.smack.packet.StanzaError; import org.jivesoftware.smack.util.StringUtils; +import org.jivesoftware.smackx.muc.MultiUserChatException.MissingMucCreationAcknowledgeException; +import org.jivesoftware.smackx.muc.MultiUserChatException.MucAlreadyJoinedException; +import org.jivesoftware.smackx.muc.MultiUserChatException.NotAMucServiceException; import org.jivesoftware.smackx.xdata.form.FillableForm; import org.jivesoftware.smackx.xdata.form.Form; @@ -47,7 +53,7 @@ public abstract class AbstractMultiUserChatIntegrationTest extends AbstractSmack public AbstractMultiUserChatIntegrationTest(SmackIntegrationTestEnvironment environment) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, - InterruptedException, TestNotPossibleException { + InterruptedException, TestNotPossibleException, MucAlreadyJoinedException, MissingMucCreationAcknowledgeException, NotAMucServiceException, XmppStringprepException { super(environment); mucManagerOne = MultiUserChatManager.getInstanceFor(conOne); mucManagerTwo = MultiUserChatManager.getInstanceFor(conTwo); @@ -55,10 +61,40 @@ public abstract class AbstractMultiUserChatIntegrationTest extends AbstractSmack List services = mucManagerOne.getMucServiceDomains(); if (services.isEmpty()) { - throw new TestNotPossibleException("No MUC (XEP-45) service found"); + throw new TestNotPossibleException("No MUC (XEP-0045) service found"); } - mucService = services.get(0); + DomainBareJid needle = null; + for (final DomainBareJid service : services) { + MultiUserChat multiUserChat = null; + try { + String roomNameLocal = String.join("-", "smack-inttest-abstract", testRunId, StringUtils.insecureRandomString(6)); + EntityBareJid mucAddress = JidCreate.entityBareFrom(Localpart.from(roomNameLocal), service.getDomain()); + multiUserChat = mucManagerOne.getMultiUserChat(mucAddress); + + createMuc(multiUserChat, "test"); + + needle = service; + break; + } catch (XMPPException.XMPPErrorException e) { + mucCreationDisallowedOrThrow(e); + LOGGER.log(Level.FINER, "MUC service " + service + " does not allow MUC creation", e); + } finally { + tryDestroy(multiUserChat); + } + } + + if (needle == null) { + throw new TestNotPossibleException("No MUC (XEP-0045) service found that allows test users to createa new room. Considered MUC services: " + services); + } + mucService = needle; + } + + static void mucCreationDisallowedOrThrow(XMPPException.XMPPErrorException e) throws XMPPErrorException { + StanzaError.Condition condition = e.getStanzaError().getCondition(); + if (condition == StanzaError.Condition.not_allowed) + return; + throw e; } /** diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java index 54083165b..aa30d5b78 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatEntityIntegrationTest.java @@ -31,6 +31,9 @@ import org.jivesoftware.smack.packet.StanzaError; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverItems; +import org.jivesoftware.smackx.muc.MultiUserChatException.MissingMucCreationAcknowledgeException; +import org.jivesoftware.smackx.muc.MultiUserChatException.MucAlreadyJoinedException; +import org.jivesoftware.smackx.muc.MultiUserChatException.NotAMucServiceException; import org.jivesoftware.smackx.muc.packet.MUCInitialPresence; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; @@ -42,13 +45,14 @@ import org.jxmpp.jid.DomainBareJid; import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityFullJid; import org.jxmpp.jid.parts.Resourcepart; +import org.jxmpp.stringprep.XmppStringprepException; @SpecificationReference(document = "XEP-0045", version = "1.34.6") public class MultiUserChatEntityIntegrationTest extends AbstractMultiUserChatIntegrationTest { public MultiUserChatEntityIntegrationTest(SmackIntegrationTestEnvironment environment) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, - SmackException.NotConnectedException, InterruptedException, TestNotPossibleException { + SmackException.NotConnectedException, InterruptedException, TestNotPossibleException, MucAlreadyJoinedException, MissingMucCreationAcknowledgeException, NotAMucServiceException, XmppStringprepException { super(environment); } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java index 406f5e164..e97cf4ac5 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java @@ -50,7 +50,7 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati public MultiUserChatIntegrationTest(SmackIntegrationTestEnvironment environment) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, - InterruptedException, TestNotPossibleException { + InterruptedException, TestNotPossibleException, MucAlreadyJoinedException, MissingMucCreationAcknowledgeException, NotAMucServiceException, XmppStringprepException { super(environment); } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatLowLevelIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatLowLevelIntegrationTest.java index 3b81ce840..c70e61c7e 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatLowLevelIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatLowLevelIntegrationTest.java @@ -1,6 +1,6 @@ /** * - * Copyright 2015-2020 Florian Schmaus + * Copyright 2015-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -68,7 +68,13 @@ public class MultiUserChatLowLevelIntegrationTest extends AbstractSmackLowLevelI final MultiUserChat muc = multiUserChatManager.getMultiUserChat(JidCreate.entityBareFrom( Localpart.from(randomMucName), mucComponent)); - MucCreateConfigFormHandle handle = muc.createOrJoin(mucNickname); + MucCreateConfigFormHandle handle; + try { + handle = muc.createOrJoin(mucNickname); + } catch (XMPPException.XMPPErrorException e) { + AbstractMultiUserChatIntegrationTest.mucCreationDisallowedOrThrow(e); + throw new TestNotPossibleException("MUC service " + mucComponent + " does not allow MUC creation", e); + } if (handle != null) { handle.makeInstant(); } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java index c662ef3f1..04ea0253c 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatOccupantIntegrationTest.java @@ -41,7 +41,10 @@ import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.StanzaError; import org.jivesoftware.smack.sm.predicates.ForEveryMessage; import org.jivesoftware.smack.util.StringUtils; +import org.jivesoftware.smackx.muc.MultiUserChatException.MissingMucCreationAcknowledgeException; +import org.jivesoftware.smackx.muc.MultiUserChatException.MucAlreadyJoinedException; import org.jivesoftware.smackx.muc.MultiUserChatException.MucConfigurationNotSupportedException; +import org.jivesoftware.smackx.muc.MultiUserChatException.NotAMucServiceException; import org.jivesoftware.smackx.muc.packet.MUCItem; import org.jivesoftware.smackx.muc.packet.MUCUser; @@ -56,13 +59,14 @@ import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.parts.Resourcepart; +import org.jxmpp.stringprep.XmppStringprepException; @SpecificationReference(document = "XEP-0045", version = "1.34.6") public class MultiUserChatOccupantIntegrationTest extends AbstractMultiUserChatIntegrationTest { public MultiUserChatOccupantIntegrationTest(SmackIntegrationTestEnvironment environment) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, - SmackException.NotConnectedException, InterruptedException, TestNotPossibleException { + SmackException.NotConnectedException, InterruptedException, TestNotPossibleException, MucAlreadyJoinedException, MissingMucCreationAcknowledgeException, NotAMucServiceException, XmppStringprepException { super(environment); } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java index 9c4eab22b..9c88f47fe 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java @@ -1,6 +1,6 @@ /** * - * Copyright 2021 Florian Schmaus, Dan Caseley + * Copyright 2021-2024 Florian Schmaus, Dan Caseley * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +32,9 @@ import java.util.stream.Collectors; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.Presence; +import org.jivesoftware.smackx.muc.MultiUserChatException.MissingMucCreationAcknowledgeException; +import org.jivesoftware.smackx.muc.MultiUserChatException.MucAlreadyJoinedException; +import org.jivesoftware.smackx.muc.MultiUserChatException.NotAMucServiceException; import org.jivesoftware.smackx.muc.packet.MUCUser; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; @@ -45,6 +48,7 @@ import org.jxmpp.jid.EntityFullJid; import org.jxmpp.jid.Jid; import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.parts.Resourcepart; +import org.jxmpp.stringprep.XmppStringprepException; @SpecificationReference(document = "XEP-0045", version = "1.34.6") @@ -52,7 +56,7 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs public MultiUserChatRolesAffiliationsPrivilegesIntegrationTest(SmackIntegrationTestEnvironment environment) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, - InterruptedException, TestNotPossibleException { + InterruptedException, TestNotPossibleException, MucAlreadyJoinedException, MissingMucCreationAcknowledgeException, NotAMucServiceException, XmppStringprepException { super(environment); } From 7f3bc3d5001c948e6c02688463256f445173b3df Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Mon, 15 Jul 2024 12:46:16 +0200 Subject: [PATCH 109/150] [sint] Correct for recent API change The commit that introduced these tests was merged at the same time with an API change. --- .../smackx/muc/ParticipantStatusIntegrationTest.java | 3 ++- .../org/jivesoftware/smackx/muc/UserStatusIntegrationTest.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/ParticipantStatusIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/ParticipantStatusIntegrationTest.java index f4ebfdd70..1bf3fdce4 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/ParticipantStatusIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/ParticipantStatusIntegrationTest.java @@ -28,6 +28,7 @@ import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityFullJid; import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.parts.Resourcepart; +import org.jxmpp.stringprep.XmppStringprepException; /** * Tests that verify the correct functionality of Smack's {@link ParticipantStatusListener}. @@ -35,7 +36,7 @@ import org.jxmpp.jid.parts.Resourcepart; @SpecificationReference(document = "XEP-0045", version = "1.34.6") public class ParticipantStatusIntegrationTest extends AbstractMultiUserChatIntegrationTest { - public ParticipantStatusIntegrationTest(SmackIntegrationTestEnvironment environment) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, TestNotPossibleException { + public ParticipantStatusIntegrationTest(SmackIntegrationTestEnvironment environment) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, TestNotPossibleException, MultiUserChatException.MucAlreadyJoinedException, MultiUserChatException.MissingMucCreationAcknowledgeException, XmppStringprepException, MultiUserChatException.NotAMucServiceException { super(environment); } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/UserStatusIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/UserStatusIntegrationTest.java index 3395d4068..201f1ba21 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/UserStatusIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/UserStatusIntegrationTest.java @@ -30,6 +30,7 @@ import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityFullJid; import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.parts.Resourcepart; +import org.jxmpp.stringprep.XmppStringprepException; /** * Tests that verify the correct functionality of Smack's {@link UserStatusListener}. @@ -37,7 +38,7 @@ import org.jxmpp.jid.parts.Resourcepart; @SpecificationReference(document = "XEP-0045", version = "1.34.6") public class UserStatusIntegrationTest extends AbstractMultiUserChatIntegrationTest { - public UserStatusIntegrationTest(SmackIntegrationTestEnvironment environment) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, TestNotPossibleException { + public UserStatusIntegrationTest(SmackIntegrationTestEnvironment environment) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, TestNotPossibleException, MultiUserChatException.MucAlreadyJoinedException, MultiUserChatException.MissingMucCreationAcknowledgeException, XmppStringprepException, MultiUserChatException.NotAMucServiceException { super(environment); } From b85be6572c48a086cacf127e5daba772d90c53db Mon Sep 17 00:00:00 2001 From: Sergey Ponomarev Date: Mon, 12 Aug 2024 08:45:54 +0300 Subject: [PATCH 110/150] build.gradle: remove clirr plugin The clirr plugin is disabled and not used --- build.gradle | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/build.gradle b/build.gradle index 1bf116655..35fad9e81 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,6 @@ buildscript { maven { url 'https://dl.bintray.com/content/aalmiray/kordamp' } } dependencies { - classpath 'org.kordamp.gradle:clirr-gradle-plugin:0.2.2' classpath "biz.aQute.bnd:biz.aQute.bnd.gradle:6.0.0" } } @@ -450,7 +449,6 @@ subprojects { apply plugin: 'maven-publish' apply plugin: 'signing' apply plugin: 'checkstyle' - apply plugin: 'org.kordamp.gradle.clirr' apply plugin: 'biz.aQute.bnd.builder' checkstyle { @@ -559,16 +557,6 @@ subprojects { sign publishing.publications.mavenJava } - clirr { - // 2018-08-14: Disabled Clirr because - // - It reports an breaking change in android.jar (seems right, but there is nothing we can do about it) - // - Only the first smack-* projects are correctly checked, - // the other ones have the output of a clirr report from a previous project - // (Look at the clirr reports). - enabled false - semver false - } - // Work around https://github.com/gradle/gradle/issues/4046 task copyJavadocDocFiles(type: Copy) { from('src/javadoc') @@ -601,18 +589,6 @@ configure (androidProjects + androidBootClasspathProjects) { } } -// There is no need to ever clirr integration test projects and the -// smack-repl project. -configure(integrationTestProjects + project(':smack-repl')) { - clirr { - enabled false - } -} - -// Disable clirr on omemo modules -project(':smack-omemo').clirr.enabled = false -project(':smack-omemo-signal').clirr.enabled = false - subprojects*.jar { manifest { from sharedManifest @@ -697,12 +673,6 @@ task jacocoRootReport(type: org.gradle.testing.jacoco.tasks.JacocoReport) { setOnlyIf { true } } -// Important to specify this task after the subprojects block -task clirrRootReport(type: org.kordamp.gradle.clirr.ClirrReportTask) { - dependsOn = subprojects.tasks.clirr - reports = files((subprojects.findAll { it.clirr.enabled == true }).tasks.clirr.xmlReport) -} - task integrationTest { description 'Verify correct functionality of Smack by running some integration tests.' dependsOn project(':smack-integration-test').tasks.run From c74ebca955e0435273f7ae67e24bcd579af200d8 Mon Sep 17 00:00:00 2001 From: Sergey Ponomarev Date: Mon, 12 Aug 2024 08:47:03 +0300 Subject: [PATCH 111/150] build.gradle: migrate from jcenter to gradlePluginPortal and upgrade biz.aQute.bnd.builder --- build.gradle | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 35fad9e81..f9bf7bfda 100644 --- a/build.gradle +++ b/build.gradle @@ -1,11 +1,6 @@ buildscript { repositories { - jcenter() - maven { url 'https://plugins.gradle.org/m2/' } - maven { url 'https://dl.bintray.com/content/aalmiray/kordamp' } - } - dependencies { - classpath "biz.aQute.bnd:biz.aQute.bnd.gradle:6.0.0" + gradlePluginPortal() } } @@ -15,6 +10,7 @@ plugins { // Use e.g. "gradle taskTree" to show its dependency tree. id 'com.dorongold.task-tree' version '1.5' id 'com.github.kt3k.coveralls' version '2.10.2' + id 'biz.aQute.bnd.builder' version '6.4.0' } ext { From 3534569a8ddc8f223d3c190888c4e40bccc475b5 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Tue, 13 Aug 2024 15:48:02 +0200 Subject: [PATCH 112/150] Add support for room admin config to MucConfigFormManager fixes SMACK-947 --- .../smackx/muc/MucConfigFormManager.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java index f46124482..1c989c8bc 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java @@ -62,6 +62,13 @@ public class MucConfigFormManager { */ public static final String MUC_ROOMCONFIG_ROOMOWNERS = "muc#roomconfig_roomowners"; + /** + * The constant String {@value}. + * + * @see XEP-0045 § 10. Owner Use Cases + */ + public static final String MUC_ROOMCONFIG_ROOMADMINS = "muc#roomconfig_roomadmins"; + /** * The constant String {@value}. */ @@ -107,6 +114,7 @@ public class MucConfigFormManager { private final MultiUserChat multiUserChat; private final FillableForm answerForm; private final List owners; + private final List admins; /** * Create a new MUC config form manager. @@ -140,6 +148,18 @@ public class MucConfigFormManager { // roomowners not supported, this should barely be the case owners = null; } + + FormField roomAdminsFormField = answerForm.getDataForm().getField(MUC_ROOMCONFIG_ROOMADMINS); + if (roomAdminsFormField != null) { + // Set 'admins' to the currently configured admins + List adminStrings = roomAdminsFormField.getValues(); + admins = new ArrayList<>(adminStrings.size()); + JidUtil.jidsFrom(adminStrings, admins, null); + } + else { + // roomadmins not supported, this should barely be the case + admins = null; + } } /** @@ -151,6 +171,15 @@ public class MucConfigFormManager { return owners != null; } + /** + * Check if the room supports room admins. + * @return true if supported, false if not. + * @see #MUC_ROOMCONFIG_ROOMADMINS + */ + public boolean supportsRoomAdmins() { + return admins != null; + } + /** * Set the owners of the room. * @@ -168,6 +197,23 @@ public class MucConfigFormManager { return this; } + /** + * Set the admins of the room. + * + * @param newAdmins a collection of JIDs to become the new admins of the room. + * @return a reference to this object. + * @throws MucConfigurationNotSupportedException if the MUC service does not support this option. + * @see #MUC_ROOMCONFIG_ROOMADMINS + */ + public MucConfigFormManager setRoomAdmins(Collection newAdmins) throws MucConfigurationNotSupportedException { + if (!supportsRoomAdmins()) { + throw new MucConfigurationNotSupportedException(MUC_ROOMCONFIG_ROOMADMINS); + } + admins.clear(); + admins.addAll(newAdmins); + return this; + } + /** * Check if the room supports a members only configuration. * @@ -420,6 +466,9 @@ public class MucConfigFormManager { if (owners != null) { answerForm.setAnswer(MUC_ROOMCONFIG_ROOMOWNERS, JidUtil.toStringList(owners)); } + if (admins != null) { + answerForm.setAnswer(MUC_ROOMCONFIG_ROOMADMINS, JidUtil.toStringList(admins)); + } multiUserChat.sendConfigurationForm(answerForm); } } From 82385ab4d0a827663123c8b60cb19e86366f6c22 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 15 Aug 2024 14:03:39 +0200 Subject: [PATCH 113/150] [muc] Add support for 'password' in room destroy XEP-0045 specifies that an optional alternate venue password value can be provided in a room destruction request and broadcast. fixes SMACK-950 --- .../smackx/muc/DefaultUserStatusListener.java | 2 +- .../smackx/muc/MultiUserChat.java | 24 +++++++++++++++++-- .../smackx/muc/UserStatusListener.java | 5 ++-- .../smackx/muc/packet/Destroy.java | 20 +++++++++++++++- .../smackx/muc/provider/MUCParserUtils.java | 6 ++++- .../muc/MultiUserChatIntegrationTest.java | 2 +- 6 files changed, 51 insertions(+), 8 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultUserStatusListener.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultUserStatusListener.java index 0ac93ccbd..e90b6993a 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultUserStatusListener.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultUserStatusListener.java @@ -82,7 +82,7 @@ public class DefaultUserStatusListener implements UserStatusListener { } @Override - public void roomDestroyed(MultiUserChat alternateMUC, String reason) { + public void roomDestroyed(MultiUserChat alternateMUC, String password, String reason) { } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java index 45d474749..9a7de8e00 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java @@ -290,7 +290,7 @@ public class MultiUserChat { } for (UserStatusListener listener : userStatusListeners) { - listener.roomDestroyed(alternateMuc, destroy.getReason()); + listener.roomDestroyed(alternateMuc, destroy.getPassword(), destroy.getReason()); } } @@ -965,12 +965,32 @@ public class MultiUserChat { * @throws InterruptedException if the calling thread was interrupted. */ public void destroy(String reason, EntityBareJid alternateJID) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { + destroy(reason, alternateJID, null); + } + + /** + * Sends a request to the server to destroy the room. The sender of the request + * should be the room's owner. If the sender of the destroy request is not the room's owner + * then the server will answer a "Forbidden" error (403). + * + * @param reason an optional reason for the room destruction. + * @param alternateJID an optional JID of an alternate location. + * @param password an optional password for the alternate location + * @throws XMPPErrorException if an error occurs while trying to destroy the room. + * An error can occur which will be wrapped by an XMPPException -- + * XMPP error code 403. The error code can be used to present more + * appropriate error messages to end-users. + * @throws NoResponseException if there was no response from the server. + * @throws NotConnectedException if the XMPP connection is not connected. + * @throws InterruptedException if the calling thread was interrupted. + */ + public void destroy(String reason, EntityBareJid alternateJID, String password) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { MUCOwner iq = new MUCOwner(); iq.setTo(room); iq.setType(IQ.Type.set); // Create the reason for the room destruction - Destroy destroy = new Destroy(alternateJID, reason); + Destroy destroy = new Destroy(alternateJID, password, reason); iq.setDestroy(destroy); try { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/UserStatusListener.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/UserStatusListener.java index 0e87cb5bd..b8d9db944 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/UserStatusListener.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/UserStatusListener.java @@ -28,7 +28,7 @@ import org.jxmpp.jid.Jid; * banned, or granted admin permissions or the room is destroyed. *

* Note that the methods {@link #kicked(Jid, String)}, {@link #banned(Jid, String)} and - * {@link #roomDestroyed(MultiUserChat, String)} will be called before the generic {@link #removed(MUCUser, Presence)} + * {@link #roomDestroyed(MultiUserChat, String, String)} will be called before the generic {@link #removed(MUCUser, Presence)} * callback will be invoked. The generic {@link #removed(MUCUser, Presence)} callback will be invoked every time the user * was removed from the MUC involuntarily. It is hence the recommended callback to listen for and act upon. *

@@ -161,10 +161,11 @@ public interface UserStatusListener { * Called when the room is destroyed. * * @param alternateMUC an alternate MultiUserChat, may be null. + * @param password a password for the alternative MultiUserChat, may be null. * @param reason the reason why the room was closed, may be null. * @see #removed(MUCUser, Presence) */ - default void roomDestroyed(MultiUserChat alternateMUC, String reason) { + default void roomDestroyed(MultiUserChat alternateMUC, String password, String reason) { } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/Destroy.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/Destroy.java index 1361f79fe..9da151c4c 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/Destroy.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/Destroy.java @@ -40,14 +40,22 @@ public class Destroy implements NamedElement, Serializable { private final String reason; private final EntityBareJid jid; + private final String password; public Destroy(Destroy other) { - this(other.jid, other.reason); + this(other.jid, other.password, other.reason); } public Destroy(EntityBareJid alternativeJid, String reason) { this.jid = alternativeJid; this.reason = reason; + this.password = null; + } + + public Destroy(EntityBareJid alternativeJid, String password, String reason) { + this.jid = alternativeJid; + this.password = password; + this.reason = reason; } /** @@ -59,6 +67,15 @@ public class Destroy implements NamedElement, Serializable { return jid; } + /** + * Returns the password of the alternate location. + * + * @return the password of the alternate location. + */ + public String getPassword() { + return password; + } + /** * Returns the reason for the room destruction. * @@ -73,6 +90,7 @@ public class Destroy implements NamedElement, Serializable { XmlStringBuilder xml = new XmlStringBuilder(this); xml.optAttribute("jid", getJid()); xml.rightAngleBracket(); + xml.optElement("password", getPassword()); xml.optElement("reason", getReason()); xml.closeElement(this); return xml; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/provider/MUCParserUtils.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/provider/MUCParserUtils.java index 897fc131b..3cfa04423 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/provider/MUCParserUtils.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/provider/MUCParserUtils.java @@ -79,6 +79,7 @@ public class MUCParserUtils { final int initialDepth = parser.getDepth(); final EntityBareJid jid = ParserUtils.getBareJidAttribute(parser); String reason = null; + String password = null; outerloop: while (true) { XmlPullParser.Event eventType = parser.next(); switch (eventType) { @@ -88,6 +89,9 @@ public class MUCParserUtils { case "reason": reason = parser.nextText(); break; + case "password": + password = parser.nextText(); + break; } break; case END_ELEMENT: @@ -100,6 +104,6 @@ public class MUCParserUtils { break; } } - return new Destroy(jid, reason); + return new Destroy(jid, password, reason); } } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java index 406f5e164..7d1173bec 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java @@ -112,7 +112,7 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati UserStatusListener userStatusListener = new UserStatusListener() { @Override - public void roomDestroyed(MultiUserChat alternateMUC, String reason) { + public void roomDestroyed(MultiUserChat alternateMUC, String password, String reason) { mucDestroyed.signal(); } }; From c99318783e13e09eff143a3ea88efa32f1a31d27 Mon Sep 17 00:00:00 2001 From: Sergey Ponomarev Date: Sun, 25 Aug 2024 09:35:50 +0200 Subject: [PATCH 114/150] [core] Make AccountManager.getRegistrationInfo() public The getRegistrationInfo() returns a registration form that may also contain a CAPTCHA. We need to get the full Registration object to get the fields. Also it should be possible to call it multiple times to update the form. Signed-off-by: Sergey Ponomarev --- .../org/jivesoftware/smackx/iqregister/AccountManager.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/AccountManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/AccountManager.java index 7a991978c..c6f32970c 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/AccountManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/AccountManager.java @@ -354,15 +354,17 @@ public final class AccountManager extends Manager { /** * Gets the account registration info from the server. * + * @return Registration information * @throws XMPPErrorException if there was an XMPP error returned. * @throws NoResponseException if there was no response from the remote entity. * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - private synchronized void getRegistrationInfo() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { + public synchronized Registration getRegistrationInfo() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { Registration reg = new Registration(); reg.setTo(connection().getXMPPServiceDomain()); info = createStanzaCollectorAndSend(reg).nextResultOrThrow(); + return info; } private StanzaCollector createStanzaCollectorAndSend(IQ req) throws NotConnectedException, InterruptedException { From 4d790aa7db42a44623b809091c9f6d00cb5d853a Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 1 Sep 2024 21:52:25 +0200 Subject: [PATCH 115/150] [xdata] Only require list-multi and list-single fields to have a value Only list-multi and list-single fields require at least one value when submitting a form. In other cases, for example XEP-0045's muc#roomconfig_roomadmins, which is of type jid-multi, is used without any values to reset the room's admins list. Fixes SMACK-946. --- .../smackx/xdata/form/FillableForm.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/form/FillableForm.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/form/FillableForm.java index 332c7fc3f..04cee2654 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/form/FillableForm.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/form/FillableForm.java @@ -30,6 +30,8 @@ import org.jivesoftware.smackx.xdata.AbstractMultiFormField; import org.jivesoftware.smackx.xdata.AbstractSingleStringValueFormField; import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.FormFieldChildElement; +import org.jivesoftware.smackx.xdata.ListMultiFormField; +import org.jivesoftware.smackx.xdata.ListSingleFormField; import org.jivesoftware.smackx.xdata.packet.DataForm; import org.jxmpp.jid.Jid; @@ -226,11 +228,20 @@ public class FillableForm extends FilledForm { if (filledFormField.getType() == FormField.Type.fixed) { throw new IllegalArgumentException(); } - if (!filledFormField.hasValueSet()) { - throw new IllegalArgumentException(); - } String fieldName = filledFormField.getFieldName(); + + boolean isListField = filledFormField instanceof ListMultiFormField + || filledFormField instanceof ListSingleFormField; + // Only list-* fields require a value to be set. Other fields types can be empty. For example MUC's + // muc#roomconfig_roomadmins, which is of type jid-multi, is submitted without values to reset the room's admin + // list. + if (isListField && !filledFormField.hasValueSet()) { + throw new IllegalArgumentException("Tried to write form field " + fieldName + " of type " + + filledFormField.getType() + + " without any values set. However, according to XEP-0045 § 3.3 fields of type list-multi or list-single must have one item set."); + } + if (!getDataForm().hasField(fieldName)) { throw new IllegalArgumentException(); } From 4f840d1066c236942f5aa6468b4b0ac555a15905 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 5 Sep 2024 10:59:23 +0200 Subject: [PATCH 116/150] [sinttest] Add error message to subscribe request failure Have a descriptive error message when a subscription request times out. --- .../smack/inttest/util/IntegrationTestRosterUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/IntegrationTestRosterUtil.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/IntegrationTestRosterUtil.java index 4a6569dcf..befa9eb23 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/IntegrationTestRosterUtil.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/IntegrationTestRosterUtil.java @@ -79,7 +79,7 @@ public class IntegrationTestRosterUtil { try { presenceRequestingRoster.sendSubscriptionRequest(presenceRequestReceiverAddress.asBareJid()); - syncPoint.waitForResult(timeout); + syncPoint.waitForResult(timeout, "Timeout while waiting for subscription request of '" + presenceRequestingAddress + "' to '" + presenceRequestReceiverAddress + "' to be answered."); } finally { presenceRequestReceiverRoster.removeSubscribeListener(subscribeListener); presenceRequestingRoster.removePresenceEventListener(presenceEventListener); From 609781b5ade55fd26f80db9c9cafba602c1b1470 Mon Sep 17 00:00:00 2001 From: hamed-sb Date: Thu, 5 Sep 2024 12:49:15 +0330 Subject: [PATCH 117/150] [core] fix toXml for UnparsedIQ --- .../org/jivesoftware/smack/packet/UnparsedIQ.java | 9 ++++++++- .../org/jivesoftware/smack/packet/IqTest.java | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/UnparsedIQ.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/UnparsedIQ.java index e363d2e30..8cd2146f8 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/UnparsedIQ.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/UnparsedIQ.java @@ -16,6 +16,8 @@ */ package org.jivesoftware.smack.packet; +import org.jivesoftware.smack.util.StringUtils; + /** * An IQ stanzas that could not be parsed because no provider was found. */ @@ -34,7 +36,12 @@ public class UnparsedIQ extends IQ { @Override protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { - xml.escape(content); + if (StringUtils.isEmpty(content)) { + xml.setEmptyElement(); + } else { + xml.rightAngleBracket(); + xml.escape(content); + } return xml; } } diff --git a/smack-core/src/test/java/org/jivesoftware/smack/packet/IqTest.java b/smack-core/src/test/java/org/jivesoftware/smack/packet/IqTest.java index 041c66981..2101daca4 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/packet/IqTest.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/packet/IqTest.java @@ -58,4 +58,19 @@ public class IqTest { IQ iq = PacketParserUtils.parseIQ(parser); assertXmlSimilar(iqXml, iq.toXML()); } + + @ParameterizedTest + @EnumSource(SmackTestUtil.XmlPullParserKind.class) + public void testUnparsedIq(SmackTestUtil.XmlPullParserKind parserKind) throws Exception { + final String iqXml = "" + + "" + + ""; + final String expected = "" + + "<query xmlns='jabber:iq:version'/>" + + ""; + + XmlPullParser parser = SmackTestUtil.getParserFor(iqXml, "iq", parserKind); + IQ iq = PacketParserUtils.parseIQ(parser); + assertXmlSimilar(expected, iq.toXML()); + } } From 93efdf3eda73c1c43f72d9a299e6bc1435b5565c Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Thu, 5 Sep 2024 15:12:28 +0200 Subject: [PATCH 118/150] [muc] State of MUC should reflect room destruction After a room is destroyed, the MultiUserChat-stored representation of the 'join' state of any occupant should be updated to reflect that the user is no longer in the room. This fixes a problem where an occupant (that not itself triggered the destruction) appears to continue be part of a room after its destruction. Additional integration test assertions are added to check for the invalid state fixed by this commit. fixes SMACK-949 --- .../smackx/muc/MultiUserChat.java | 1 + .../muc/MultiUserChatIntegrationTest.java | 58 ++++++++++++++++++- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java index 9383d9e28..511a9820f 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java @@ -292,6 +292,7 @@ public class MultiUserChat { for (UserStatusListener listener : userStatusListeners) { listener.roomDestroyed(alternateMuc, destroy.getPassword(), destroy.getReason()); } + userHasLeft(); } if (isUserStatusModification) { diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java index b407c5f31..be59229c9 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java @@ -17,6 +17,7 @@ package org.jivesoftware.smackx.muc; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -87,7 +88,7 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati /** - * Asserts that a user is notified when a room is destroyed. + * Asserts that an owner is notified of room destruction when they destroy a room. * * @throws TimeoutException when roomDestroyed event doesn't get fired * @throws Exception when other errors occur @@ -95,9 +96,9 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati @SmackIntegrationTest(section = "10.9", quote = "A room owner MUST be able to destroy a room, especially if the room is persistent... The room removes all " + "users from the room... and destroys the room") - public void mucDestroyTest() throws TimeoutException, Exception { + public void mucDestroyOwnerTest() throws TimeoutException, Exception { - EntityBareJid mucAddress = getRandomRoom("smack-inttest-destroy"); + EntityBareJid mucAddress = getRandomRoom("smack-inttest-destroy-owner"); MultiUserChat muc = mucManagerOne.getMultiUserChat(mucAddress); createMuc(muc, Resourcepart.from("one-" + randomString)); @@ -127,11 +128,62 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati } Set joinedRooms = mucManagerOne.getJoinedRooms(); + assertFalse(muc.isJoined(), "Expected " + conOne.getUser() + " to no longer be in room " + mucAddress + " after it was destroyed, but it is still in."); assertEquals(0, joinedRooms.size(), "Expected " + conOne.getUser() + " to no longer be in any rooms after " + mucAddress + " was destroyed. But it is still in " + joinedRooms); assertEquals(0, muc.getOccupantsCount(), "Expected room " + mucAddress + " to no longer have any occupants after it was destroyed (but it has)."); assertNull(muc.getNickname()); } + /** + * Asserts that an occupant of a room is notified when a room is destroyed. + * + * @throws TimeoutException when roomDestroyed event doesn't get fired + * @throws Exception when other errors occur + */ + @SmackIntegrationTest(section = "10.9", quote = + "A room owner MUST be able to destroy a room, especially if the room is persistent... The room removes all " + + "users from the room... and destroys the room") + public void mucDestroyTestOccupant() throws TimeoutException, Exception { + + EntityBareJid mucAddress = getRandomRoom("smack-inttest-destroy-occupant"); + + MultiUserChat mucAsSeenByOwner = mucManagerOne.getMultiUserChat(mucAddress); + MultiUserChat mucAsSeenByParticipant = mucManagerTwo.getMultiUserChat(mucAddress); + createMuc(mucAsSeenByOwner, Resourcepart.from("one-" + randomString)); + + // These would be a test implementation bug, not assertion failure. + mucAsSeenByParticipant.join(Resourcepart.from("two-" + randomString)); + if (!mucManagerTwo.getJoinedRooms().contains(mucAddress)) { + tryDestroy(mucAsSeenByOwner); + throw new IllegalStateException("Expected user to have joined a room '" + mucAddress + "' (but does not appear to have done so)."); + } + + + final SimpleResultSyncPoint mucDestroyed = new SimpleResultSyncPoint(); + + UserStatusListener userStatusListener = new UserStatusListener() { + @Override + public void roomDestroyed(MultiUserChat alternateMUC, String password, String reason) { + mucDestroyed.signal(); + } + }; + + mucAsSeenByParticipant.addUserStatusListener(userStatusListener); + + try { + mucAsSeenByOwner.destroy("Dummy reason", null); + assertResult(mucDestroyed, "Expected " + conTwo.getUser() + " to be notified of destruction of room " + mucAddress + " (but was not)."); + } finally { + mucAsSeenByParticipant.removeUserStatusListener(userStatusListener); + } + + Set joinedRooms = mucManagerTwo.getJoinedRooms(); + assertFalse(mucAsSeenByParticipant.isJoined(), "Expected " + conTwo.getUser() + " to no longer be in room " + mucAddress + " after it was destroyed, but it is still in."); + assertEquals(0, joinedRooms.size(), "Expected " + conTwo.getUser() + " to no longer be in any rooms after " + mucAddress + " was destroyed. But it is still in " + joinedRooms); + assertEquals(0, mucAsSeenByParticipant.getOccupantsCount(), "Expected room " + mucAddress + " to no longer have any occupants after it was destroyed (but it has)."); + assertNull(mucAsSeenByParticipant.getNickname()); + } + @SmackIntegrationTest public void mucNameChangeTest() throws XmppStringprepException, MucAlreadyJoinedException, MissingMucCreationAcknowledgeException, From c85bcadd81c23ca68e97115c8e7cfb6b99bede6f Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Fri, 6 Sep 2024 21:52:50 +0200 Subject: [PATCH 119/150] Fixes spelling (includes one API change) Mostly benign changes. Added one new method to replace a method with a spelling mistake in its name. Kept the old method, marked as 'deprecated'. --- build.gradle | 10 ++--- resources/fix-a-javadoc.sh | 4 +- resources/getCopyright.sh | 2 +- .../android/ServerPingWithAlarmManager.java | 2 +- .../debugger/android/AndroidDebugger.java | 2 +- smack-core/build.gradle | 2 +- .../org/jivesoftware/smack/MessageTest.java | 2 +- .../smack/test/SmackTestCase.java | 2 +- .../smack/AbstractXMPPConnection.java | 2 +- .../jivesoftware/smack/AsyncButOrdered.java | 6 +-- .../smack/ConnectionConfiguration.java | 19 ++++---- .../smack/SASLAuthentication.java | 2 +- .../java/org/jivesoftware/smack/Smack.java | 2 +- .../smack/SmackConfiguration.java | 2 +- .../jivesoftware/smack/XMPPConnection.java | 6 +-- .../smack/XmppInputOutputFilter.java | 4 +- .../ModularXmppClientToServerConnection.java | 2 +- .../jivesoftware/smack/datatypes/UInt16.java | 2 +- .../smack/debugger/ConsoleDebugger.java | 2 +- .../smack/debugger/JulDebugger.java | 2 +- .../smack/debugger/SmackDebugger.java | 2 +- .../smack/filter/package-info.java | 2 +- .../smack/fsm/StateDescriptor.java | 4 +- .../smack/fsm/StateDescriptorGraph.java | 2 +- .../smack/packet/ExtensionElement.java | 2 +- .../org/jivesoftware/smack/packet/IQ.java | 4 +- .../org/jivesoftware/smack/packet/Nonza.java | 2 +- .../org/jivesoftware/smack/packet/Stanza.java | 2 +- .../smack/packet/StanzaBuilder.java | 4 +- .../smack/packet/StreamError.java | 4 +- .../smack/provider/package-info.java | 2 +- .../smack/sasl/SASLMechanism.java | 2 +- .../java/org/jivesoftware/smack/util/MAC.java | 2 +- .../java/org/jivesoftware/smack/util/MD5.java | 2 +- .../smack/util/PacketParserUtils.java | 6 +-- .../jivesoftware/smack/util/ParserUtils.java | 2 +- .../org/jivesoftware/smack/util/SHA1.java | 2 +- .../jivesoftware/smack/util/StringUtils.java | 2 +- .../smack/util/dns/package-info.java | 4 +- .../jivesoftware/smack/DummyConnection.java | 4 +- .../smack/test/util/MemoryLeakTestUtil.java | 2 +- .../smackx/hashes/HashManager.java | 2 +- .../smackx/hoxt/package-info.java | 2 +- .../jivesoftware/smackx/iot/package-info.java | 4 +- .../message_markup/element/package-info.java | 2 +- .../smackx/reference/package-info.java | 2 +- .../ExplicitMessageEncryptionElementTest.java | 4 +- .../jivesoftware/smackx/FileTransferTest.java | 2 +- .../smackx/OfflineMessageManagerTest.java | 2 +- .../smackx/ServiceDiscoveryManagerTest.java | 2 +- .../address/packet/MultipleAddresses.java | 2 +- .../blocking/BlockingCommandManager.java | 4 +- .../smackx/bookmarks/BookmarkManager.java | 10 ++--- .../ibb/InBandBytestreamManager.java | 2 +- .../socks5/Socks5BytestreamManager.java | 10 ++--- .../bytestreams/socks5/Socks5Client.java | 2 +- .../smackx/caps/EntityCapsManager.java | 4 +- .../smackx/commands/AdHocCommandManager.java | 2 +- .../delay/filter/DelayedStanzaFilter.java | 4 +- .../smackx/disco/ServiceDiscoveryManager.java | 2 +- .../smackx/disco/packet/DiscoverInfo.java | 2 +- .../filetransfer/IncomingFileTransfer.java | 2 +- .../smackx/filetransfer/StreamNegotiator.java | 2 +- .../smackx/filetransfer/package-info.java | 2 +- .../smackx/geoloc/GeoLocationManager.java | 2 +- .../smackx/iqprivate/packet/PrivateData.java | 2 +- .../smackx/jingle/element/Jingle.java | 2 +- .../smackx/jingle/element/JingleContent.java | 2 +- .../smackx/jiveproperties/package-info.java | 2 +- .../jivesoftware/smackx/muc/Affiliate.java | 4 +- .../muc/DefaultParticipantStatusListener.java | 2 +- .../smackx/muc/DefaultUserStatusListener.java | 2 +- .../smackx/muc/MucConfigFormManager.java | 2 +- .../smackx/muc/MultiUserChat.java | 44 +++++++++---------- .../smackx/muc/MultiUserChatManager.java | 4 +- .../smackx/muc/ParticipantStatusListener.java | 4 +- .../org/jivesoftware/smackx/muc/RoomInfo.java | 8 ++-- .../smackx/muc/UserStatusListener.java | 6 +-- .../jivesoftware/smackx/muc/package-info.java | 2 +- .../jivesoftware/smackx/nick/packet/Nick.java | 2 +- .../jivesoftware/smackx/pep/PepManager.java | 2 +- .../jivesoftware/smackx/ping/PingManager.java | 6 +-- .../smackx/privacy/package-info.java | 2 +- .../smackx/privacy/packet/PrivacyItem.java | 2 +- .../smackx/pubsub/PubSubManager.java | 2 +- .../smackx/pubsub/SimplePayload.java | 2 +- .../smackx/search/ReportedData.java | 2 +- .../smackx/vcardtemp/packet/VCard.java | 4 +- .../smackx/xdata/BooleanFormField.java | 2 +- .../smackx/xhtmlim/package-info.java | 2 +- .../org/jivesoftware/smack/chat/Chat.java | 2 +- .../org/jivesoftware/smack/roster/Roster.java | 28 ++++++------ .../smack/roster/RosterEntry.java | 6 +-- .../smack/roster/RosterGroup.java | 2 +- .../smack/XmppConnectionStressTest.java | 8 ++-- .../SmackIntegrationTestFramework.java | 2 +- .../inttest/XmppConnectionDescriptor.java | 8 +++- .../smack/inttest/XmppConnectionManager.java | 2 +- .../smack/inttest/package-info.java | 2 +- .../smack/LoginIntegrationTest.java | 2 +- .../roster/LowLevelRosterIntegrationTest.java | 2 +- .../AbstractMultiUserChatIntegrationTest.java | 4 +- ...AffiliationsPrivilegesIntegrationTest.java | 2 +- .../smackx/pubsub/PubSubIntegrationTest.java | 2 +- ...egrationTestXmppConnectionManagerTest.java | 2 +- .../jivesoftware/smackx/SmackExtensions.java | 2 +- .../org/jivesoftware/smackx/package-info.java | 4 +- .../smackx/jingleold/JingleManager.java | 4 +- .../smackx/jingleold/JingleNegotiator.java | 2 +- .../smackx/jingleold/JingleSession.java | 6 +-- .../smackx/jingleold/JingleSessionState.java | 2 +- .../CreatedJingleSessionListener.java | 2 +- .../listeners/JingleSessionListener.java | 2 +- .../jingleold/media/JingleMediaSession.java | 6 +-- .../smackx/jingleold/media/PayloadType.java | 2 +- .../jingleold/mediaimpl/jmf/AudioChannel.java | 2 +- .../mediaimpl/jspeex/AudioMediaSession.java | 2 +- .../jingleold/nat/TransportNegotiator.java | 2 +- .../jingleold/nat/TransportResolver.java | 4 +- .../provider/JingleTransportProvider.java | 4 +- .../smackx/workgroup/agent/AgentRoster.java | 6 +-- .../smackx/workgroup/agent/Offer.java | 4 +- .../smackx/workgroup/agent/OfferListener.java | 2 +- .../smackx/workgroup/user/Workgroup.java | 10 ++--- .../smackx/xroster/RosterExchangeManager.java | 4 +- .../smackx/omemo/OmemoService.java | 2 +- .../smackx/omemo/package-info.java | 2 +- .../omemo/util/OmemoMessageBuilder.java | 6 +-- .../smackx/ox/util/OpenPgpPubSubUtil.java | 2 +- .../smack/util/dns/javax/JavaxResolver.java | 2 +- .../sasl/javax/SASLExternalMechanism.java | 4 +- .../sasl/provided/SASLDigestMD5Mechanism.java | 6 +-- .../smack/sm/predicates/tcp/package-info.java | 2 +- .../smack/tcp/XMPPTCPConnection.java | 12 ++--- .../smack/tcp/XmppTcpTransportModule.java | 14 +++--- .../rce/RemoteXmppTcpConnectionEndpoints.java | 2 +- .../WebSocketConnectionAttemptState.java | 2 +- .../XmppWebSocketTransportModule.java | 4 +- ...bSocketRemoteConnectionEndpointLookup.java | 4 +- .../jivesoftware/smack/xml/XmlPullParser.java | 2 +- 140 files changed, 270 insertions(+), 265 deletions(-) diff --git a/build.gradle b/build.gradle index 1bf116655..cd988132e 100644 --- a/build.gradle +++ b/build.gradle @@ -209,7 +209,7 @@ allprojects { options.compilerArgs = [ '-Xlint:all', // Set '-options' because a non-java7 javac will emit a - // warning if source/traget is set to 1.7 and + // warning if source/target is set to 1.7 and // bootclasspath is *not* set. // TODO implement a sound heuristic to determine a java7 // rt.jar on the build host. And if none is found, @@ -268,7 +268,7 @@ allprojects { if (JavaVersion.current().isJava8Compatible()) { tasks.withType(Javadoc) { // The '-quiet' as second argument is actually a hack, - // since the one paramater addStringOption doesn't seem to + // since the one parameter addStringOption doesn't seem to // work, we extra add '-quiet', which is added anyway by // gradle. // TODO: This enables all doclint check but @@ -342,7 +342,7 @@ configure (junit4Projects) { // We need to evaluate the child projects first because // - javadocAll needs the smack-core child to have already resolved -// the jXMPP/MiniDNS dependencies, so that we can the resovled +// the jXMPP/MiniDNS dependencies, so that we can the resolved // version to link to those project's javadoc. // - We use the child's project description as description for the // Maven POM. @@ -418,7 +418,7 @@ task maybeCheckForSnapshotDependencies { // Don't check for Snapshot dependencies if this is a snapshot. onlyIf { isReleaseVersion } // Run in the execution phase, not in configuration phase, as the - // 'each' forces the runtime configuration to be resovled, which + // 'each' forces the runtime configuration to be resolved, which // causes "Cannot change dependencies of configuration after it // has been included in dependency resolution." errors. // See https://discuss.gradle.org/t/23153 @@ -795,7 +795,7 @@ def getResolvedVersion(queriedProject = 'smack-core', component) { .resolvedArtifacts .findAll { // 'it' is of type ResolvedArtifact, 'id' of - // Component*Artifcat*Identifier, and we check the + // Component*Artifact*Identifier, and we check the // ComponentIdentifier. it.id.getComponentIdentifier() instanceof org.gradle.api.artifacts.component.ModuleComponentIdentifier } diff --git a/resources/fix-a-javadoc.sh b/resources/fix-a-javadoc.sh index 94e8f31fd..a300a1a59 100755 --- a/resources/fix-a-javadoc.sh +++ b/resources/fix-a-javadoc.sh @@ -29,7 +29,7 @@ SMACK_EXCEPTIONS[SmackException]="if Smack detected an exceptional situation." SMACK_EXCEPTIONS[XMPPException]="if an XMPP protocol error was received." SMACK_EXCEPTIONS[SmackSaslException]="if a SASL specific error occurred." SMACK_EXCEPTIONS[SASLErrorException]="if a SASL protocol error was returned." -SMACK_EXCEPTIONS[NotAMucServiceException]="if the entity is not a MUC serivce." +SMACK_EXCEPTIONS[NotAMucServiceException]="if the entity is not a MUC service." SMACK_EXCEPTIONS[NoSuchAlgorithmException]="if no such algorithm is available." SMACK_EXCEPTIONS[KeyManagementException]="if there was a key mangement error." SMACK_EXCEPTIONS[XmppStringprepException]="if the provided string is invalid." @@ -53,7 +53,7 @@ SMACK_EXCEPTIONS[Exception]="if an exception occurred." SMACK_EXCEPTIONS[TestNotPossibleException]="if the test is not possible." SMACK_EXCEPTIONS[TimeoutException]="if there was a timeout." SMACK_EXCEPTIONS[IllegalStateException]="if an illegal state was encountered" -SMACK_EXCEPTIONS[NoSuchPaddingException]="if the requested padding mechanism is not availble." +SMACK_EXCEPTIONS[NoSuchPaddingException]="if the requested padding mechanism is not available." SMACK_EXCEPTIONS[BadPaddingException]="if the input data is not padded properly." SMACK_EXCEPTIONS[InvalidKeyException]="if the key is invalid." SMACK_EXCEPTIONS[IllegalBlockSizeException]="if the input data length is incorrect." diff --git a/resources/getCopyright.sh b/resources/getCopyright.sh index c34fd87da..fdde88b0f 100755 --- a/resources/getCopyright.sh +++ b/resources/getCopyright.sh @@ -15,7 +15,7 @@ for p in $SUBPROJECTS; do sort | \ # Remove duplicates uniq | \ - # Split multi Copyright statemtents, e.g. "2001-2013 FooBar, 2014 Baz" + # Split multi Copyright statements, e.g. "2001-2013 FooBar, 2014 Baz" tr ',' '\n' | \ # Remove whitespaces resulting from the previous split sed "s/^[ \t]*//" | \ diff --git a/smack-android-extensions/src/main/java/org/jivesoftware/smackx/ping/android/ServerPingWithAlarmManager.java b/smack-android-extensions/src/main/java/org/jivesoftware/smackx/ping/android/ServerPingWithAlarmManager.java index a81f51ade..3d217efcb 100644 --- a/smack-android-extensions/src/main/java/org/jivesoftware/smackx/ping/android/ServerPingWithAlarmManager.java +++ b/smack-android-extensions/src/main/java/org/jivesoftware/smackx/ping/android/ServerPingWithAlarmManager.java @@ -163,7 +163,7 @@ public final class ServerPingWithAlarmManager extends Manager { private static AlarmManager sAlarmManager; /** - * Register a pending intent with the AlarmManager to be broadcasted every half hour and + * Register a pending intent with the AlarmManager to be broadcast every half hour and * register the alarm broadcast receiver to receive this intent. The receiver will check all * known questions if a ping is Necessary when invoked by the alarm intent. * diff --git a/smack-android/src/main/java/org/jivesoftware/smackx/debugger/android/AndroidDebugger.java b/smack-android/src/main/java/org/jivesoftware/smackx/debugger/android/AndroidDebugger.java index 068dab202..930fb9195 100644 --- a/smack-android/src/main/java/org/jivesoftware/smackx/debugger/android/AndroidDebugger.java +++ b/smack-android/src/main/java/org/jivesoftware/smackx/debugger/android/AndroidDebugger.java @@ -28,7 +28,7 @@ import android.util.Log; * implementation, therefore {@link org.jivesoftware.smack.debugger.JulDebugger} is preferred. *

* It is possible to not only print the raw sent and received stanzas but also the interpreted - * packets by Smack. By default interpreted packets won't be printed. To enable this feature + * packets by Smack. By default,interpreted packets won't be printed. To enable this feature * just change the printInterpreted static variable to true. * */ diff --git a/smack-core/build.gradle b/smack-core/build.gradle index f449ec5b7..d29c04d80 100644 --- a/smack-core/build.gradle +++ b/smack-core/build.gradle @@ -28,7 +28,7 @@ dependencies { testFixturesApi "org.jxmpp:jxmpp-jid:$jxmppVersion:tests" testFixturesApi "org.xmlunit:xmlunit-core:$xmlUnitVersion" - // Explictily add assertj-core which is a dependency of + // Explicitly add assertj-core which is a dependency of // xmlunit-assertj, but gradle fails to resolves it with: // Execution failed for task ':smack-core:compileTestJava'. // > Could not resolve all files for configuration ':smack-core:testCompileClasspath'. diff --git a/smack-core/src/integration-test/java/org/jivesoftware/smack/MessageTest.java b/smack-core/src/integration-test/java/org/jivesoftware/smack/MessageTest.java index 75b4f6915..bcded200c 100644 --- a/smack-core/src/integration-test/java/org/jivesoftware/smack/MessageTest.java +++ b/smack-core/src/integration-test/java/org/jivesoftware/smack/MessageTest.java @@ -60,7 +60,7 @@ public class MessageTest extends SmackTestCase { } Message message = (Message) collector.nextResult(2500); - assertNotNull("Message not recieved from remote user", message); + assertNotNull("Message not received from remote user", message); } /** diff --git a/smack-core/src/integration-test/java/org/jivesoftware/smack/test/SmackTestCase.java b/smack-core/src/integration-test/java/org/jivesoftware/smack/test/SmackTestCase.java index 601540abe..ae25506ba 100644 --- a/smack-core/src/integration-test/java/org/jivesoftware/smack/test/SmackTestCase.java +++ b/smack-core/src/integration-test/java/org/jivesoftware/smack/test/SmackTestCase.java @@ -487,7 +487,7 @@ public abstract class SmackTestCase extends TestCase { } /** - * Returns the name of the configuration file related to this test case. By default all + * Returns the name of the configuration file related to this test case. By default,all * the test cases will use the same configuration file. However, it's possible to override the * default configuration by providing a file of the form .xml * (e.g. RosterTest.xml). 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 2b2dd5ee8..ae24f7f2b 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java @@ -128,7 +128,7 @@ import org.jxmpp.stringprep.XmppStringprepException; import org.jxmpp.util.XmppStringUtils; /** - * This abstract class is commonly used as super class for XMPP connection mechanisms like TCP and BOSH. Hence it + * This abstract class is commonly used as super class for XMPP connection mechanisms like TCP and BOSH. Hence, it * provides the methods for connection state management, like {@link #connect()}, {@link #login()} and * {@link #disconnect()} (which are deliberately not provided by the {@link XMPPConnection} interface). *

diff --git a/smack-core/src/main/java/org/jivesoftware/smack/AsyncButOrdered.java b/smack-core/src/main/java/org/jivesoftware/smack/AsyncButOrdered.java index 526e3cd2e..5788370ff 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AsyncButOrdered.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/AsyncButOrdered.java @@ -53,14 +53,14 @@ import java.util.concurrent.Executor; public class AsyncButOrdered { /** - * A map with the currently pending runnables for a given key. Note that this is a weak hash map so we do not have - * to take care of removing the keys ourselfs from the map. + * A map with the currently pending runnables for a given key. Note that this is a weak hash map, so we do not have + * to take care of removing the keys ourselves from the map. */ private final Map> pendingRunnables = new WeakHashMap<>(); /** * A marker map if there is an active thread for the given key. Holds the responsible handler thread if one is - * active, otherwise the key is non-existend in the map. + * active, otherwise the key is non-existent in the map. */ private final Map threadActiveMap = new HashMap<>(); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java b/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java index 9561a158d..11e931f1a 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java @@ -88,7 +88,7 @@ import org.minidns.util.InetAddressUtil; /** * The connection configuration used for XMPP client-to-server connections. A well configured XMPP service will * typically only require you to provide two parameters: The XMPP address, also known as the JID, of the user and the - * password. All other configuration parameters could ideally be determined automatically by Smack. Hence it is often + * password. All other configuration parameters could ideally be determined automatically by Smack. Hence, it is often * enough to call {@link Builder#setXmppAddressAndPassword(CharSequence, String)}. *

* Technically there are typically at least two parameters required: Some kind of credentials for authentication. And @@ -248,7 +248,7 @@ public abstract class ConnectionConfiguration { stanzaIdSourceFactory = builder.stanzaIdSourceFactory; - // If the enabledSaslmechanisms are set, then they must not be empty + // If the enabledSaslMechanisms are set, then they must not be empty assert enabledSaslMechanisms == null || !enabledSaslMechanisms.isEmpty(); } @@ -267,7 +267,7 @@ public abstract class ConnectionConfiguration { context = SSLContext.getInstance("TLS"); } - // TODO: Remove the block below once we removed setKeystorePath(), setKeystoreType(), setCallbackHanlder() and + // TODO: Remove the block below once we removed setKeystorePath(), setKeystoreType(), setCallbackHandler() and // setPKCS11Library() in the builder, and all related fields and the parameters of this function. if (keyManagers == null) { keyManagers = Builder.getKeyManagersFrom(keystoreType, keystorePath, callbackHandler, pkcs11Library); @@ -583,7 +583,7 @@ public abstract class ConnectionConfiguration { * Returns true if the connection is going to use stream compression. Stream compression * will be requested after TLS was established (if TLS was enabled) and only if the server * offered stream compression. With stream compression network traffic can be reduced - * up to 90%. By default compression is disabled. + * up to 90%. By default,compression is disabled. * * @return true if the connection is going to use stream compression. */ @@ -592,7 +592,7 @@ public abstract class ConnectionConfiguration { } /** - * Check if the given SASL mechansism is enabled in this connection configuration. + * Check if the given SASL mechanism is enabled in this connection configuration. * * @param saslMechanism TODO javadoc me please * @return true if the given SASL mechanism is enabled, false otherwise. @@ -607,7 +607,7 @@ public abstract class ConnectionConfiguration { /** * Return the explicitly enabled SASL mechanisms. May return null if no SASL mechanisms where - * explicitly enabled, i.e. all SALS mechanisms supported and announced by the service will be considered. + * explicitly enabled, i.e. all SASL mechanisms supported and announced by the service will be considered. * * @return the enabled SASL mechanisms or null. */ @@ -1090,8 +1090,7 @@ public abstract class ConnectionConfiguration { } /** - * Sets if an initial available presence will be sent to the server. By default - * an available presence will be sent to the server indicating that this presence + * Sets if an initial available presence will be sent to the server. By default, * an available presence will be sent to the server indicating that this presence * is not online and available to receive messages. If you want to log in without * being 'noticed' then pass a false value. * @@ -1266,7 +1265,7 @@ public abstract class ConnectionConfiguration { * Sets if the connection is going to use compression (default false). * * Compression is only activated if the server offers compression. With compression network - * traffic can be reduced up to 90%. By default compression is disabled. + * traffic can be reduced up to 90%. By default,compression is disabled. * * @param compressionEnabled if the connection is going to use compression on the HTTP level. * @return a reference to this object. @@ -1324,7 +1323,7 @@ public abstract class ConnectionConfiguration { } else { InputStream stream = TLSUtils.getDefaultTruststoreStreamIfPossible(); try { - // Note that PKCS12 keystores need a password one some Java platforms. Hence we try the famous + // Note that PKCS12 keystores need a password one some Java platforms. Hence, we try the famous // 'changeit' here. See https://bugs.openjdk.java.net/browse/JDK-8194702 char[] password = "changeit".toCharArray(); try { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java b/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java index 4685bf4af..7d545bb45 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java @@ -53,7 +53,7 @@ import org.jxmpp.jid.EntityBareJid; * *

Once TLS has been negotiated (i.e. the connection has been secured) it is possible to * register with the server or authenticate using SASL. If the - * server supports SASL then Smack will try to authenticate using SASL..

+ * server supports SASL then Smack will try to authenticate using SASL.

* *

The server may support many SASL mechanisms to use for authenticating. Out of the box * Smack provides several SASL mechanisms, but it is possible to register new SASL Mechanisms. Use diff --git a/smack-core/src/main/java/org/jivesoftware/smack/Smack.java b/smack-core/src/main/java/org/jivesoftware/smack/Smack.java index 6608bba4b..daa7a18b4 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/Smack.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/Smack.java @@ -30,7 +30,7 @@ public class Smack { public static final String SMACK_PACKAGE = SMACK_ORG + ".smack"; /** - * Returns the Smack version information, eg "1.3.0". + * Returns the Smack version information, e.g."1.3.0". * * @return the Smack version information. */ diff --git a/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java b/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java index f3316c8ed..ef1101cff 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java @@ -102,7 +102,7 @@ public final class SmackConfiguration { private static HostnameVerifier defaultHostnameVerififer; /** - * Returns the Smack version information, eg "1.3.0". + * Returns the Smack version information, e.g."1.3.0". * * @return the Smack version information. * @deprecated use {@link Smack#getVersion()} instead. 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 f7543e724..cbf05cc6e 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java @@ -96,7 +96,7 @@ import org.jxmpp.jid.EntityFullJid; *

  • other - e.g., {@link #addStanzaListener(StanzaListener, StanzaFilter)}
  • * *

    - * Asynchronous callbacks are run decoupled from the connections main event loop. Hence a callback triggered by + * Asynchronous callbacks are run decoupled from the connections main event loop. Hence, a callback triggered by * stanza B may (appear to) invoked before a callback triggered by stanza A, even though stanza A arrived before B. *

    *

    @@ -242,7 +242,7 @@ public interface XMPPConnection { *

    * * @param stanza the stanza to send. - * @return {@code true} if the stanza was successfully scheduled to be send, {@code false} otherwise. + * @return {@code true} if the stanza was successfully scheduled to be sent, {@code false} otherwise. * @throws NotConnectedException if the connection is not connected. * @since 4.4.0 * @deprecated use {@link #sendStanzaNonBlocking(Stanza)} instead. @@ -265,7 +265,7 @@ public interface XMPPConnection { * @param stanza the stanza to send. * @param timeout how long to wait before giving up, in units of {@code unit}. * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter. - * @return {@code true} if the stanza was successfully scheduled to be send, {@code false} otherwise. + * @return {@code true} if the stanza was successfully scheduled to be sent, {@code false} otherwise. * @throws NotConnectedException if the connection is not connected. * @throws InterruptedException if the calling thread was interrupted. * @since 4.4.0 diff --git a/smack-core/src/main/java/org/jivesoftware/smack/XmppInputOutputFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/XmppInputOutputFilter.java index 97fdff246..4f0c68b0a 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/XmppInputOutputFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/XmppInputOutputFilter.java @@ -57,8 +57,8 @@ public interface XmppInputOutputFilter { } /** - * The returned {@link ByteBuffer} is going to get fliped by the caller. The callee must not flip the buffer. - * @param inputData the data this methods needs to process. + * The returned {@link ByteBuffer} is going to get flipped by the caller. The callee must not flip the buffer. + * @param inputData the data this method needs to process. * @return a {@link ByteBuffer} or {@code null} if no data could be produced. * @throws IOException in case an I/O exception occurs. */ diff --git a/smack-core/src/main/java/org/jivesoftware/smack/c2s/ModularXmppClientToServerConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/c2s/ModularXmppClientToServerConnection.java index b24b00704..495720deb 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/c2s/ModularXmppClientToServerConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/c2s/ModularXmppClientToServerConnection.java @@ -390,7 +390,7 @@ public final class ModularXmppClientToServerConnection extends AbstractXMPPConne // Ignore successorStateVertex if the only way to the final state is via the initial state. This happens // typically if we are in the ConnectedButUnauthenticated state on the way to ResourceboundAndAuthenticated, - // where we do not want to walk via InstantShutdown/Shtudown in a cycle over the initial state towards this + // where we do not want to walk via InstantShutdown/Shutdown in a cycle over the initial state towards this // state. if (walkStateGraphContext.wouldCauseCycle(successorStateVertex)) { // Ignore this successor. 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 271de8cbc..8df4cd2f4 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 @@ -19,7 +19,7 @@ package org.jivesoftware.smack.datatypes; import org.jivesoftware.smack.util.NumberUtil; /** - * A number representing an unsigned 16-bit integer. Can be used for values with the XML schema type "xs:unsingedShort". + * A number representing an unsigned 16-bit integer. Can be used for values with the XML schema type "xs:unsignedShort". */ public final class UInt16 extends Scalar implements Comparable { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/debugger/ConsoleDebugger.java b/smack-core/src/main/java/org/jivesoftware/smack/debugger/ConsoleDebugger.java index a8ef6c00a..12d140aad 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/debugger/ConsoleDebugger.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/debugger/ConsoleDebugger.java @@ -28,7 +28,7 @@ import org.jivesoftware.smack.util.ExceptionUtil; * even block the thread since only one thread may print at a time. *

    * It is possible to not only print the raw sent and received stanzas but also the interpreted - * packets by Smack. By default interpreted packets won't be printed. To enable this feature + * packets by Smack. By default,interpreted packets won't be printed. To enable this feature * just change the printInterpreted static variable to true. *

    * diff --git a/smack-core/src/main/java/org/jivesoftware/smack/debugger/JulDebugger.java b/smack-core/src/main/java/org/jivesoftware/smack/debugger/JulDebugger.java index db0772271..015bb813b 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/debugger/JulDebugger.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/debugger/JulDebugger.java @@ -27,7 +27,7 @@ import org.jivesoftware.smack.XMPPConnection; * even block the thread since only one thread may print at a time. *

    * It is possible to not only print the raw sent and received stanzas but also the interpreted - * packets by Smack. By default interpreted packets won't be printed. To enable this feature + * packets by Smack. By default,interpreted packets won't be printed. To enable this feature * just change the printInterpreted static variable to true. *

    * diff --git a/smack-core/src/main/java/org/jivesoftware/smack/debugger/SmackDebugger.java b/smack-core/src/main/java/org/jivesoftware/smack/debugger/SmackDebugger.java index 82ca10b62..4f936b72d 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/debugger/SmackDebugger.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/debugger/SmackDebugger.java @@ -57,7 +57,7 @@ public abstract class SmackDebugger { * * @param user the user@host/resource that has just logged in */ - // TODO: Should be replaced with a connection listener authenticed(). + // TODO: Should be replaced with a connection listener authenticated(). public abstract void userHasLogged(EntityFullJid user); /** diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/package-info.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/package-info.java index 01f2e0461..c130b93ff 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/package-info.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/package-info.java @@ -23,7 +23,7 @@ *
  • {@link StanzaIdFilter}: filters for stanzas with a particular stanza ID
  • *
  • {@link ToMatchesFilter}: filters for stanzas that are sent to a particular address
  • *
  • {@link FromMatchesFilter}: filters for stanzas that are sent from a particular address
  • - *
  • {@link ExtensionElementFilter}: filters for stanzas that have a particular stanza exentsion element
  • + *
  • {@link ExtensionElementFilter}: filters for stanzas that have a particular stanza extension element
  • *
  • {@link AndFilter}: implements the logical AND operation over two or more filters
  • *
  • {@link OrFilter}: implements the logical OR operation over two or more filters
  • *
  • {@link NotFilter}: implements the logical NOT operation on a filter
  • diff --git a/smack-core/src/main/java/org/jivesoftware/smack/fsm/StateDescriptor.java b/smack-core/src/main/java/org/jivesoftware/smack/fsm/StateDescriptor.java index 8f399480e..29c298c76 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/fsm/StateDescriptor.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/fsm/StateDescriptor.java @@ -118,7 +118,7 @@ public abstract class StateDescriptor { if (stateClassConstructor != null) { stateClassConstructor.setAccessible(true); } else { - // TODO: Add validation check that if stateClassConstructor is 'null' the cosntructState() method is overriden. + // TODO: Add validation check that if stateClassConstructor is 'null' the constructState() method is overridden. } String className = getClass().getSimpleName(); @@ -155,7 +155,7 @@ public abstract class StateDescriptor { clazz = Class.forName(clazzName); } catch (ClassNotFoundException e) { // The state descriptor class is not in classpath, which probably means that the smack module is not loaded - // into the classpath. Hence we can silently ignore that. + // into the classpath. Hence, we can silently ignore that. LOGGER.log(Level.FINEST, "Ignoring unknown state descriptor '" + clazzName + "'", e); return; } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/fsm/StateDescriptorGraph.java b/smack-core/src/main/java/org/jivesoftware/smack/fsm/StateDescriptorGraph.java index 41bb29f59..224e1fab0 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/fsm/StateDescriptorGraph.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/fsm/StateDescriptorGraph.java @@ -215,7 +215,7 @@ public class StateDescriptorGraph { inferredForwardEdges.put(predecessor, backwardsEdge); } } - // Ensure that the intial node has their successors inferred. + // Ensure that the initial node has their successors inferred. for (Class inferredSuccessorOfInitialStateDescriptor : inferredForwardEdges.getAll(initialStatedescriptorClass)) { initialNode.getElement().addSuccessor(inferredSuccessorOfInitialStateDescriptor); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/ExtensionElement.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/ExtensionElement.java index 5a7f00650..5f4ed1b6e 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/ExtensionElement.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/ExtensionElement.java @@ -19,7 +19,7 @@ package org.jivesoftware.smack.packet; /** * Interface to represent XMPP extension elements. Unlike {@link XmlElement}, every non-abstract class that implements * {@link ExtensionElement} must have a static final QNAME member of the type {@link javax.xml.namespace.QName}. This - * allows type-safe functions like {@link StanzaView#getExtension(Class)}. Hence this is a marker interface. + * allows type-safe functions like {@link StanzaView#getExtension(Class)}. Hence, this is a marker interface. *

    * Use this class when implementing new extension elements when possible. This means that every instance of your * implemented class must represent an XML element of the same qualified name. diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java index 1881f4c23..a38386bfa 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java @@ -95,7 +95,7 @@ public abstract class IQ extends Stanza implements IqView { /** * Sets the type of the IQ packet. *

    - * Since the type of an IQ must present, an IllegalArgmentException will be thrown when type is + * Since the type of an IQ must present, an IllegalArgumentException will be thrown when type is * null. *

    * @@ -182,7 +182,7 @@ public abstract class IQ extends Stanza implements IqView { // Add the query section if there is one. IQChildElementXmlStringBuilder iqChildElement = getIQChildElementBuilder( new IQChildElementXmlStringBuilder(getChildElementName(), getChildElementNamespace(), null, xml.getXmlEnvironment())); - // TOOD: Document the cases where iqChildElement is null but childElementName not. And if there are none, change + // TODO: Document the cases where iqChildElement is null but childElementName not. And if there are none, change // the logic. if (iqChildElement == null) { return; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/Nonza.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/Nonza.java index a86a4e1db..ece665543 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/Nonza.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/Nonza.java @@ -18,7 +18,7 @@ package org.jivesoftware.smack.packet; /** - * A Nonza, i.e everything that is not a stanza as defined + * A Nonza, i.e. everything that is not a stanza as defined * RFC 6120 8. Stanzas are {@link Message}, {@link Presence} and {@link IQ}. * Everything else should sublcass this class instead of {@link Stanza}. *

    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 7123e82f8..435a344b6 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 @@ -98,7 +98,7 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { protected Stanza(StanzaBuilder stanzaBuilder) { if (stanzaBuilder.stanzaIdSource != null) { id = stanzaBuilder.stanzaIdSource.getNewStanzaId(); - // Note that some stanza ID sources, e.g. StanzaBuilder.PresenceBuilder.EMPTY return null here. Hence we + // Note that some stanza ID sources, e.g. StanzaBuilder.PresenceBuilder.EMPTY return null here. Hence, we // only check that the returned string is not empty. assert StringUtils.isNullOrNotEmpty(id); usedStanzaIdSource = stanzaBuilder.stanzaIdSource; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaBuilder.java index ec8bdac3c..2cc2a20ed 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaBuilder.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaBuilder.java @@ -87,9 +87,9 @@ public abstract class StanzaBuilder> implements Stanz } /** - * Set the recipent address of the stanza. + * Set the recipient address of the stanza. * - * @param to whoe the stanza is being sent to. + * @param to whom the stanza is being sent. * @return a reference to this builder. * @throws XmppStringprepException if the provided character sequence is not a valid XMPP address. * @see #to(Jid) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/StreamError.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/StreamError.java index f034be9d3..a58599de8 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/StreamError.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/StreamError.java @@ -58,9 +58,9 @@ import org.jivesoftware.smack.util.XmlStringBuilder; * stream has been authenticated * policy-violation the entity has violated some local service * policy. - * remote-connection-failed Rthe server is unable to properly connect + * remote-connection-failed the server is unable to properly connect * to a remote entity. - * resource-constraint Rthe server lacks the system resources necessary + * resource-constraint the server lacks the system resources necessary * to service the stream. * restricted-xml the entity has attempted to send restricted XML * features. diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/package-info.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/package-info.java index 5e40c5639..21fafdfcb 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/package-info.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/package-info.java @@ -16,7 +16,7 @@ */ /** - * The Smack provider architecture is a system for plugging in custom XML parsing of staza extensions + * The Smack provider architecture is a system for plugging in custom XML parsing of stanza extensions * ({@link org.jivesoftware.smack.packet.ExtensionElement}, {@link org.jivesoftware.smack.packet.IQ} stanzas and * {@link org.jivesoftware.smack.packet.Nonza}. Hence, there are the the following providers: *

      diff --git a/smack-core/src/main/java/org/jivesoftware/smack/sasl/SASLMechanism.java b/smack-core/src/main/java/org/jivesoftware/smack/sasl/SASLMechanism.java index f1c00ef19..24330a6ac 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/sasl/SASLMechanism.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/sasl/SASLMechanism.java @@ -358,7 +358,7 @@ public abstract class SASLMechanism implements Comparable { * SASLprep the given String. The resulting String is in UTF-8. * * @param string the String to sasl prep. - * @return the given String SASL preped + * @return the given String SASL prepped * @see RFC 4013 - SASLprep: Stringprep Profile for User Names and Passwords */ protected static String saslPrep(String string) { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/MAC.java b/smack-core/src/main/java/org/jivesoftware/smack/util/MAC.java index 4d78d24f8..df177204e 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/MAC.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/MAC.java @@ -33,7 +33,7 @@ public class MAC { HMAC_SHA1 = Mac.getInstance(HMACSHA1); } catch (NoSuchAlgorithmException e) { - // Smack wont be able to function normally if this exception is thrown, wrap it into + // Smack won't be able to function normally if this exception is thrown, wrap it into // an ISE and make the user aware of the problem. throw new IllegalStateException(e); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/MD5.java b/smack-core/src/main/java/org/jivesoftware/smack/util/MD5.java index 26c0547fd..d81c4de5a 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/MD5.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/MD5.java @@ -31,7 +31,7 @@ public class MD5 { MD5_DIGEST = MessageDigest.getInstance(StringUtils.MD5); } catch (NoSuchAlgorithmException e) { - // Smack wont be able to function normally if this exception is thrown, wrap it into + // Smack won't be able to function normally if this exception is thrown, wrap it into // an ISE and make the user aware of the problem. throw new IllegalStateException(e); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java index 042402299..c04514075 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java @@ -230,7 +230,7 @@ public class PacketParserUtils { // Assume this is the end tag of the start tag at the // beginning of this method. Typical examples where this // happens are body elements containing the empty string, - // ie. , which appears to be valid XMPP, or a + // i.e. , which appears to be valid XMPP, or a // least it's not explicitly forbidden by RFC 6121 5.2.3 return ""; } else { @@ -850,7 +850,7 @@ public class PacketParserUtils { throws XmlPullParserException, IOException { ParserUtils.assertAtStartTag(parser); assert parser.getNamespace().equals(StartTls.NAMESPACE); - int initalDepth = parser.getDepth(); + int initialDepth = parser.getDepth(); boolean required = false; outerloop: while (true) { XmlPullParser.Event event = parser.next(); @@ -864,7 +864,7 @@ public class PacketParserUtils { } break; case END_ELEMENT: - if (parser.getDepth() == initalDepth) { + if (parser.getDepth() == initialDepth) { break outerloop; } break; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/ParserUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/ParserUtils.java index 64c18a7fb..12ce7da7d 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/ParserUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/ParserUtils.java @@ -146,7 +146,7 @@ public class ParserUtils { } /** - * Prase a string to a boolean value as per "xs:boolean". Valid input strings are "true", "1" for true, and "false", "0" for false. + * Phrase a string to a boolean value as per "xs:boolean". Valid input strings are "true", "1" for true, and "false", "0" for false. * * @param booleanString the input string. * @return the boolean representation of the input string diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/SHA1.java b/smack-core/src/main/java/org/jivesoftware/smack/util/SHA1.java index 89144530b..3c7d53ac4 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/SHA1.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/SHA1.java @@ -31,7 +31,7 @@ public class SHA1 { SHA1_DIGEST = MessageDigest.getInstance(StringUtils.SHA1); } catch (NoSuchAlgorithmException e) { - // Smack wont be able to function normally if this exception is thrown, wrap it into + // Smack won't be able to function normally if this exception is thrown, wrap it into // an ISE and make the user aware of the problem. throw new IllegalStateException(e); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java index 5ebe4c116..041ddde5a 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java @@ -343,7 +343,7 @@ public class StringUtils { try { randomString(charBuffer, random, alphabet, numRandomChars); } catch (IOException e) { - // This should never happen if we calcuate the buffer size correctly. + // This should never happen if we calculate the buffer size correctly. throw new AssertionError(e); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/dns/package-info.java b/smack-core/src/main/java/org/jivesoftware/smack/util/dns/package-info.java index f06cdab84..1fb7e9b3b 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/dns/package-info.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/dns/package-info.java @@ -61,8 +61,8 @@ *

      *

      Best Practices

      *

      - * We recommend that applications using Smack's DNSSEC API do not ask the user if DNSSEC is avaialble. Instead they - * should check for DNSSEC suport on every connection attempt. Once DNSSEC support has been discovered, the application + * We recommend that applications using Smack's DNSSEC API do not ask the user if DNSSEC is available. Instead they + * should check for DNSSEC support on every connection attempt. Once DNSSEC support has been discovered, the application * should use the `needsDnssec` mode for all future connection attempts. The same scheme can be applied when using DANE. * This approach is similar to the scheme established by to HTTP Strict * Transport Security" (HSTS, RFC 6797. diff --git a/smack-core/src/testFixtures/java/org/jivesoftware/smack/DummyConnection.java b/smack-core/src/testFixtures/java/org/jivesoftware/smack/DummyConnection.java index 7e105d58b..7df852975 100644 --- a/smack-core/src/testFixtures/java/org/jivesoftware/smack/DummyConnection.java +++ b/smack-core/src/testFixtures/java/org/jivesoftware/smack/DummyConnection.java @@ -39,9 +39,9 @@ import org.jxmpp.stringprep.XmppStringprepException; * A dummy implementation of {@link XMPPConnection}, intended to be used during * unit tests. * - * Instances store any packets that are delivered to be send using the + * Instances store any packets that are delivered to be sent using the * {@link #sendStanza(Stanza)} method in a blocking queue. The content of this queue - * can be inspected using {@link #getSentPacket()}. Typically these queues are + * can be inspected using {@link #getSentPacket()}. Typically, these queues are * used to retrieve a message that was generated by the client. * * Packets that should be processed by the client to simulate a received stanza diff --git a/smack-core/src/testFixtures/java/org/jivesoftware/smack/test/util/MemoryLeakTestUtil.java b/smack-core/src/testFixtures/java/org/jivesoftware/smack/test/util/MemoryLeakTestUtil.java index 6746e8f13..1eccfd75a 100644 --- a/smack-core/src/testFixtures/java/org/jivesoftware/smack/test/util/MemoryLeakTestUtil.java +++ b/smack-core/src/testFixtures/java/org/jivesoftware/smack/test/util/MemoryLeakTestUtil.java @@ -41,7 +41,7 @@ import org.jxmpp.stringprep.XmppStringprepException; * Note that this test is based on the assumption that it is possible to trigger a full garbage collection run, which is * not the case. See also this * stackoverflow - * question. Hence the {@link #triggerGarbageCollection()} method defined in this class is not portable and depends + * question. Hence, the {@link #triggerGarbageCollection()} method defined in this class is not portable and depends * on implementation depended Java Virtual Machine behavior. *

      * diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/hashes/HashManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/hashes/HashManager.java index b3f0c3db4..68aa79ba7 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/hashes/HashManager.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/hashes/HashManager.java @@ -47,7 +47,7 @@ import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.hashes.element.HashElement; /** - * Manager that can be used to determine support for hash functions. By default the Manager announces support for + * Manager that can be used to determine support for hash functions. By default,the Manager announces support for * XEP-0300, as well as for the recommended set of hash algorithms. Those contain SHA256, SHA384, SHA512, SHA3-256, * SHA3-384, SHA3-512, BLAKE2B256, BLAKE2B384 and BLAKE2B512. Those algorithms got recommended here: * https://xmpp.org/extensions/xep-0300.html#recommendations. diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/package-info.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/package-info.java index 1b357afa8..9ca583637 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/package-info.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/package-info.java @@ -103,7 +103,7 @@ * AbstractHttpOverXmpp.Data data = new AbstractHttpOverXmpp.Data(child); * * // create request - * HttpOverXmppReq req = HttpOverXmppReq.buider() + * HttpOverXmppReq req = HttpOverXmppReq.builder() * .setMethod(HttpMethod.POST) * .setResource("/mailbox") * .setHeaders(headers) diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/package-info.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/package-info.java index 0b3803a4f..c4b261a27 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/package-info.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/package-info.java @@ -146,7 +146,7 @@ *
        * 
        * IoTDiscoveryManager iotDiscoveryManager = IoTDiscoveryManager.getInstanceFor(connection);
      - * iotDiscovyerManager.registerThing(thing);
      + * iotDiscoveryManager.registerThing(thing);
        * 
        * 
      *

      @@ -162,7 +162,7 @@ * Things can usually only be used by other things if they are friends. Since a * thing normally can't decide on its own if an incoming friendship request * should be granted or not, we can delegate this decision to a provisioning - * service. Smack provides the `IoTProvisinoManager` to deal with friendship and + * service. Smack provides the `IoTProvisionManager` to deal with friendship and * provisioning. *

      *

      diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/package-info.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/package-info.java index 5246c33ff..f1d6e981e 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/package-info.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/package-info.java @@ -21,7 +21,7 @@ *

      Usage

      *

      * The most important class is the {@link org.jivesoftware.smackx.message_markup.element.MarkupElement} class, which - * contains a Builder to construct message markup.. + * contains a Builder to construct message markup. *

      *

      * To start creating a Message Markup Extension, call diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/reference/package-info.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/reference/package-info.java index 821577179..fc8f020be 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/reference/package-info.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/reference/package-info.java @@ -29,7 +29,7 @@ * *

        * 
      - * Message message = new Message("Alice is a realy nice person.");
      + * Message message = new Message("Alice is a really nice person.");
        * BareJid alice = JidCreate.bareFrom("alice@capulet.lit");
        * ReferenceManager.addMention(message, 0, 5, alice);
        * 
      diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/eme/ExplicitMessageEncryptionElementTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/eme/ExplicitMessageEncryptionElementTest.java
      index dc14db131..b9364b01f 100644
      --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/eme/ExplicitMessageEncryptionElementTest.java
      +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/eme/ExplicitMessageEncryptionElementTest.java
      @@ -39,7 +39,7 @@ public class ExplicitMessageEncryptionElementTest extends SmackTestSuite {
           public void addToMessageTest() {
               Message message = StanzaBuilder.buildMessage().build();
       
      -        // Check inital state (no elements)
      +        // Check initial state (no elements)
               assertNull(ExplicitMessageEncryptionElement.from(message));
               assertFalse(ExplicitMessageEncryptionElement.hasProtocol(message,
                       ExplicitMessageEncryptionElement.ExplicitMessageEncryptionProtocol.omemoVAxolotl));
      @@ -75,7 +75,7 @@ public class ExplicitMessageEncryptionElementTest extends SmackTestSuite {
               assertTrue(ExplicitMessageEncryptionElement.hasProtocol(message,
                       ExplicitMessageEncryptionElement.ExplicitMessageEncryptionProtocol.omemoVAxolotl));
       
      -        // Check, if adding additional OMEMO wont add another element
      +        // Check, if adding additional OMEMO won't add another element
               ExplicitMessageEncryptionElement.set(messageBuilder,
                       ExplicitMessageEncryptionElement.ExplicitMessageEncryptionProtocol.omemoVAxolotl);
       
      diff --git a/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/FileTransferTest.java b/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/FileTransferTest.java
      index b3ecc362a..fc9c6d933 100644
      --- a/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/FileTransferTest.java
      +++ b/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/FileTransferTest.java
      @@ -109,7 +109,7 @@ public class FileTransferTest extends SmackTestCase {
                   fail();
               }
               byte [] array = queue.take();
      -        assertEquals("Recieved file not equal to sent file.", testTransfer, array);
      +        assertEquals("Received file not equal to sent file.", testTransfer, array);
           }
       
       
      diff --git a/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/OfflineMessageManagerTest.java b/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/OfflineMessageManagerTest.java
      index 13d4bd23c..5efb0799a 100644
      --- a/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/OfflineMessageManagerTest.java
      +++ b/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/OfflineMessageManagerTest.java
      @@ -50,7 +50,7 @@ public class OfflineMessageManagerTest extends SmackTestCase {
           /**
            * While user2 is connected but unavailable, user1 sends 2 messages to user1. User2 then
            * performs some "Flexible Offline Message Retrieval" checking the number of offline messages,
      -     * retriving the headers, then the real messages of the headers and finally removing the
      +     * retrieving the headers, then the real messages of the headers and finally removing the
            * loaded messages.
            */
           public void testReadAndDelete() {
      diff --git a/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/ServiceDiscoveryManagerTest.java b/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/ServiceDiscoveryManagerTest.java
      index 5d56d85ba..71ba8d7d2 100644
      --- a/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/ServiceDiscoveryManagerTest.java
      +++ b/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/ServiceDiscoveryManagerTest.java
      @@ -90,7 +90,7 @@ public class ServiceDiscoveryManagerTest extends SmackTestCase {
            */
           public void testXHTMLFeature() {
               // Check for local XHTML service support
      -        // By default the XHTML service support is enabled in all the connections
      +        // By default,the XHTML service support is enabled in all the connections
               assertTrue(XHTMLManager.isServiceEnabled(getConnection(0)));
               assertTrue(XHTMLManager.isServiceEnabled(getConnection(1)));
               // Check for XHTML support in connection1 from connection2
      diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/address/packet/MultipleAddresses.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/address/packet/MultipleAddresses.java
      index fba5979ce..6f9e63e81 100644
      --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/address/packet/MultipleAddresses.java
      +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/address/packet/MultipleAddresses.java
      @@ -93,7 +93,7 @@ public class MultipleAddresses implements ExtensionElement {
       
           /**
            * Returns the list of addresses that matches the specified type. Examples of address
      -     * type are: TO, CC, BCC, etc..
      +     * type are: TO, CC, BCC, etc.
            *
            * @param type Examples of address type are: TO, CC, BCC, etc.
            * @return the list of addresses that matches the specified type.
      diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/blocking/BlockingCommandManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/blocking/BlockingCommandManager.java
      index 6769c9f5b..330cfbc8c 100644
      --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/blocking/BlockingCommandManager.java
      +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/blocking/BlockingCommandManager.java
      @@ -44,13 +44,13 @@ import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
       import org.jxmpp.jid.Jid;
       
       /**
      - * Block communications with contancts and other entities using XEP-0191.
      + * Block communications with contacts and other entities using XEP-0191.
        * Allows to
        * 
        *
      • Check push notifications support
      • *
      • Get blocking list
      • *
      • Block contact
      • - *
      • Unblock conact
      • + *
      • Unblock contact
      • *
      • Unblock all
      • *
      * diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkManager.java index fe8323953..9d00ec626 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkManager.java @@ -103,7 +103,7 @@ public final class BookmarkManager { * * @param name the name of the conference * @param jid the jid of the conference - * @param isAutoJoin whether or not to join this conference automatically on login + * @param isAutoJoin whether to join this conference automatically on login * @param nickname the nickname to use for the user when joining the conference * @param password the password to use for the user when joining the conference * @throws XMPPErrorException thrown when there is an issue retrieving the current bookmarks from @@ -166,7 +166,7 @@ public final class BookmarkManager { * Returns an unmodifiable collection of all bookmarked urls. * * @return returns an unmodifiable collection of all bookmarked urls. - * @throws XMPPErrorException thrown when there is a problem retriving bookmarks from the server. + * @throws XMPPErrorException thrown when there is a problem retrieving bookmarks from the server. * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. @@ -181,8 +181,8 @@ public final class BookmarkManager { * * @param URL the url of the bookmark * @param name the name of the bookmark - * @param isRSS whether or not the url is an rss feed - * @throws XMPPErrorException thrown when there is an error retriving or saving bookmarks from or to + * @param isRSS whether the url is an RSS feed + * @throws XMPPErrorException thrown when there is an error retrieving or saving bookmarks from or to * the server * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException if the XMPP connection is not connected. @@ -210,7 +210,7 @@ public final class BookmarkManager { * Removes a url from the bookmarks. * * @param bookmarkURL the url of the bookmark to remove - * @throws XMPPErrorException thrown if there is an error retriving or saving bookmarks from or to + * @throws XMPPErrorException thrown if there is an error retrieving or saving bookmarks from or to * the server. * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException if the XMPP connection is not connected. diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java index 9061a5606..823df54e1 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java @@ -511,7 +511,7 @@ public final class InBandBytestreamManager extends Manager implements Bytestream } /** - * Returns the list of session IDs that should be ignored by the InitialtionListener + * Returns the list of session IDs that should be ignored by the InitiationListener * * @return list of session IDs */ diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java index 673f7a989..a0dd45581 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java @@ -139,7 +139,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream /* timeout for connecting to the SOCKS5 proxy selected by the target */ private int proxyConnectionTimeout = 10000; - /* blacklist of errornous SOCKS5 proxies */ + /* blacklist of erroneous SOCKS5 proxies */ private final Set proxyBlacklist = Collections.synchronizedSet(new HashSet()); /* remember the last proxy that worked to prioritize it */ @@ -390,7 +390,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream } /** - * Set whether or not the bytestream manager will annouce the local stream host(s), i.e. the local SOCKS5 proxy. + * Set whether the bytestream manager will announce the local stream host(s), i.e. the local SOCKS5 proxy. * * @param announceLocalStreamHost TODO javadoc me please * @see #isAnnouncingLocalStreamHostEnabled() @@ -580,7 +580,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream proxyInfo = serviceDiscoveryManager.discoverInfo(item.getEntityID()); } catch (NoResponseException | XMPPErrorException e) { - // blacklist errornous server + // blacklist erroneous server proxyBlacklist.add(item.getEntityID()); continue; } @@ -627,7 +627,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream streamHosts.addAll(response.getStreamHosts()); } catch (Exception e) { - // blacklist errornous proxies + // blacklist erroneous proxies this.proxyBlacklist.add(proxy); } } @@ -796,7 +796,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream } /** - * Returns the list of session IDs that should be ignored by the InitialtionListener + * Returns the list of session IDs that should be ignored by the InitiationListener * * @return list of session IDs */ diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Client.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Client.java index 7f80e8260..e4444c6ac 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Client.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Client.java @@ -138,7 +138,7 @@ public class Socks5Client { byte[] connectionRequest; byte[] connectionResponse; /* - * use DataInputStream/DataOutpuStream to assure read and write is completed in a single + * use DataInputStream/DataOutputStream to assure read and write is completed in a single * statement */ DataInputStream in = new DataInputStream(socket.getInputStream()); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java index 64fc70451..c15cdf131 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java @@ -91,7 +91,7 @@ import org.jxmpp.util.cache.LruCache; * but XEP-0030 then XEP-0030 mechanisms are transparently used. *

      *

      - * The caches used by Smack for Entity Capabilities is non-persisent per default. However, it is is also possible to set + * The caches used by Smack for Entity Capabilities is non-persistent per default. However, it is is also possible to set * a persistent Entity Capabilities cache, which is recommended. *

      *

      Examples

      @@ -226,7 +226,7 @@ public final class EntityCapsManager extends Manager { /** * Get the Node version (node#ver) of a JID. Returns a String or null if - * EntiyCapsManager does not have any information. + * EntityCapsManager does not have any information. * * @param jid TODO javadoc me please * the user (Full JID) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandManager.java index 49bf9c0cd..4f4b0652b 100755 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandManager.java @@ -654,7 +654,7 @@ public final class AdHocCommandManager extends Manager { public AdHocCommandHandler getCommandInstance() throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { String sessionId; - // TODO: The code below contains a race condition. Use CopncurrentHashMap.computeIfAbsent() to remove the + // TODO: The code below contains a race condition. Use ConcurrentHashMap.computeIfAbsent() to remove the // race condition once Smack's minimum Android API level 24 or higher. int attempt = 0; do { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/delay/filter/DelayedStanzaFilter.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/delay/filter/DelayedStanzaFilter.java index 054ed42cf..90c30f563 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/delay/filter/DelayedStanzaFilter.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/delay/filter/DelayedStanzaFilter.java @@ -23,14 +23,14 @@ import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smackx.delay.DelayInformationManager; /** - * Filters stanza with delay information, ie. stanzas that got delayed for some reason + * Filters stanza with delay information, i.e. stanzas that got delayed for some reason */ public final class DelayedStanzaFilter implements StanzaFilter { public static final StanzaFilter INSTANCE = new DelayedStanzaFilter(); /** - * Filters stanzas that got not delayed, ie. have no delayed information + * Filters stanzas that got not delayed, i.e. have no delayed information */ public static final StanzaFilter NOT_DELAYED_STANZA = new NotFilter(INSTANCE); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java index 6e43fbc9a..520806d0c 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java @@ -294,7 +294,7 @@ public final class ServiceDiscoveryManager extends Manager { /** * Returns all identities of this client as unmodifiable Collection. * - * @return all identies as set + * @return all identities as a set */ public Set getIdentities() { Set res = new HashSet<>(identities); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java index abe18f630..23be5dee5 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java @@ -215,7 +215,7 @@ public class DiscoverInfo extends IQ implements DiscoverInfoView { * * @param category category the category to look for. * @param type type the type to look for. - * @return a list of Identites with the given category and type. + * @return a list of Identities with the given category and type. */ public List getIdentities(String category, String type) { List res = new ArrayList<>(identities.size()); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/IncomingFileTransfer.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/IncomingFileTransfer.java index c09e9fcb2..9a17438d0 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/IncomingFileTransfer.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/IncomingFileTransfer.java @@ -51,7 +51,7 @@ import org.jivesoftware.smack.util.CloseableUtil; * The second way that a file can be received through this class is by invoking * the {@link #receiveFile(File)} method. This method returns immediately and * takes as its parameter a file on the local file system where the file - * recieved from the transfer will be put. + * received from the transfer will be put. * * @author Alexander Wenckus */ diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/StreamNegotiator.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/StreamNegotiator.java index adf7297e5..0fc025827 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/StreamNegotiator.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/StreamNegotiator.java @@ -52,7 +52,7 @@ public abstract class StreamNegotiator extends Manager { } /** - * A event manager for stream initiation requests send to us. + * An event manager for stream initiation requests send to us. *

      * Those are typical XEP-45 Open or XEP-65 Bytestream IQ requests. The even key is in the format * "initiationFrom + '\t' + streamId" diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/package-info.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/package-info.java index 505394d1e..a05f6d56c 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/package-info.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/package-info.java @@ -144,7 +144,7 @@ *

    • **isDone()** - Similar to getProgress() except it returns a _boolean_. If the state is rejected, canceled, error, * or complete then true will be returned and false otherwise.
    • *
    • **getError()** - If there is an error during the file transfer this method will return the type of error that - * occured.
    • + * occurred. *
    *

    Examples

    *

    diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/geoloc/GeoLocationManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/geoloc/GeoLocationManager.java index f29306251..eb91bec55 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/geoloc/GeoLocationManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/geoloc/GeoLocationManager.java @@ -43,7 +43,7 @@ import org.jxmpp.jid.Jid; *
    * To publish a UserLocation, please use {@link #publishGeoLocation(GeoLocation)} method. This will publish the node. *
    - * To stop publishing a UserLocation, please use {@link #stopPublishingGeolocation()} method. This will send a disble publishing signal. + * To stop publishing a UserLocation, please use {@link #stopPublishingGeolocation()} method. This will send a disable publishing signal. *
    * To add a {@link PepEventListener} in order to remain updated with other users GeoLocation, use {@link #addGeoLocationListener(PepEventListener)} method. *
    diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/packet/PrivateData.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/packet/PrivateData.java index 058b0c2d5..c6670c900 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/packet/PrivateData.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/packet/PrivateData.java @@ -41,7 +41,7 @@ public interface PrivateData { String getNamespace(); /** - * Returns the XML reppresentation of the PrivateData. + * Returns the XML representation of the PrivateData. * * @return the private data as XML. */ diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/Jingle.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/Jingle.java index ea36bcc31..4fb09922c 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/Jingle.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/Jingle.java @@ -52,7 +52,7 @@ import org.jxmpp.jid.FullJid; * | transport-info * | transport-reject * | transport-replace - * │ initator (RECOMMENDED for session initiate, NOT RECOMMENDED otherwise, full JID, XEP-0166 § 7.1) + * │ initiator (RECOMMENDED for session initiate, NOT RECOMMENDED otherwise, full JID, XEP-0166 § 7.1) * │ responder (RECOMMENDED for session accept, NOT RECOMMENDED otherwise, full JID. XEP-0166 § 7.1) * │ sid (REQUIRED, SHOULD match XML Nmtoken production) * │ diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleContent.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleContent.java index ab5680c1d..702183dd2 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleContent.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleContent.java @@ -71,7 +71,7 @@ public final class JingleContent implements XmlElement { private final JingleContentTransport transport; /** - * Creates a content description.. + * Creates a content description. */ private JingleContent(Creator creator, String disposition, String name, Senders senders, JingleContentDescription description, JingleContentTransport transport) { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/package-info.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/package-info.java index 45a9fe3e9..a5ea271a5 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/package-info.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/package-info.java @@ -70,7 +70,7 @@ chat.sendMessage(message); *

      *
    • When you send a Java object as a property, only clients running Java will be able to interpret the data. So, * consider using a series of primitive values to transfer data instead.
    • - *
    • Objects sent as property values must implement Serialiable. Additionally, both the sender and receiver must have + *
    • Objects sent as property values must implement Serializable. Additionally, both the sender and receiver must have * identical versions of the class, or a serialization exception will occur when de-serializing the object.
    • *
    • Serialized objects can potentially be quite large, which will use more bandwidth and server resources.
    • *
    diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/Affiliate.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/Affiliate.java index 3e3648f26..d3e034c6c 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/Affiliate.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/Affiliate.java @@ -55,10 +55,10 @@ public class Affiliate { } /** - * Returns the affiliation of the afffiliated user. Possible affiliations are: "owner", "admin", + * Returns the affiliation of the affiliated user. Possible affiliations are: "owner", "admin", * "member", "outcast". This information will always be available. * - * @return the affiliation of the afffiliated user. + * @return the affiliation of the affiliated user. */ public MUCAffiliation getAffiliation() { return affiliation; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultParticipantStatusListener.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultParticipantStatusListener.java index c9d809cd2..a496077bc 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultParticipantStatusListener.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultParticipantStatusListener.java @@ -25,7 +25,7 @@ import org.jxmpp.jid.parts.Resourcepart; * Default implementation of the ParticipantStatusListener interface.

    * * This class does not provide any behavior by default. It just avoids having - * to implement all the inteface methods if the user is only interested in implementing + * to implement all the interface methods if the user is only interested in implementing * some of the methods. * * @author Gaston Dombiak diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultUserStatusListener.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultUserStatusListener.java index e90b6993a..44e396fb0 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultUserStatusListener.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultUserStatusListener.java @@ -23,7 +23,7 @@ import org.jxmpp.jid.Jid; * Default implementation of the UserStatusListener interface.

    * * This class does not provide any behavior by default. It just avoids having - * to implement all the inteface methods if the user is only interested in implementing + * to implement all the interface methods if the user is only interested in implementing * some of the methods. * * @author Gaston Dombiak diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java index 1c989c8bc..b847cd025 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucConfigFormManager.java @@ -285,7 +285,7 @@ public class MucConfigFormManager { /** - * Check if the room supports its visibility being controlled vioa configuration. + * Check if the room supports its visibility being controlled via configuration. * * @return true if supported, false if not. */ diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java index 9383d9e28..fbbc1fdc5 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java @@ -351,7 +351,7 @@ public class MultiUserChat { * @throws NoResponseException if there was no response from the remote entity. * @throws XMPPErrorException if there was an XMPP error returned. * @throws InterruptedException if the calling thread was interrupted. - * @throws NotAMucServiceException if the entity is not a MUC serivce. + * @throws NotAMucServiceException if the entity is not a MUC service. * @see XEP-45 7.2 Entering a Room */ private Presence enter(MucEnterConfiguration conf) throws NotConnectedException, NoResponseException, @@ -365,7 +365,7 @@ public class MultiUserChat { // field is in the form "roomName@service/nickname" Presence joinPresence = conf.getJoinPresence(this); - // Setup the messageListeners and presenceListeners *before* the join presence is send. + // Set up the messageListeners and presenceListeners *before* the join presence is sent. connection.addStanzaListener(messageListener, fromRoomGroupchatFilter); StanzaFilter presenceFromRoomFilter = new AndFilter(fromRoomFilter, StanzaTypeFilter.PRESENCE, @@ -401,12 +401,12 @@ public class MultiUserChat { StanzaCollector presenceStanzaCollector = null; final Presence reflectedSelfPresence; try { - // This stanza collector will collect the final self presence from the MUC, which also signals that we have successful entered the MUC. + // This stanza collector will collect the final self presence from the MUC, which also signals that we have successfully entered the MUC. StanzaCollector selfPresenceCollector = connection.createStanzaCollectorAndSend(responseFilter, joinPresence); - StanzaCollector.Configuration presenceStanzaCollectorConfguration = StanzaCollector.newConfiguration().setCollectorToReset( + StanzaCollector.Configuration presenceStanzaCollectorConfiguration = StanzaCollector.newConfiguration().setCollectorToReset( selfPresenceCollector).setStanzaFilter(presenceFromRoomFilter); // This stanza collector is used to reset the timeout of the selfPresenceCollector. - presenceStanzaCollector = connection.createStanzaCollector(presenceStanzaCollectorConfguration); + presenceStanzaCollector = connection.createStanzaCollector(presenceStanzaCollectorConfiguration); reflectedSelfPresence = selfPresenceCollector.nextResultOrThrow(conf.getTimeout()); } catch (NotConnectedException | InterruptedException | NoResponseException | XMPPErrorException e) { @@ -423,15 +423,15 @@ public class MultiUserChat { synchronized (presenceListener) { // Only continue after we have received *and* processed the reflected self-presence. Since presences are // handled in an extra listener, we may return from enter() without having processed all presences of the - // participants, resulting in a e.g. to low participant counter after enter(). Hence we wait here until the + // participants, resulting in a e.g. to low participant counter after enter(). Hence, we wait here until the // processing is done. while (!processedReflectedSelfPresence) { presenceListener.wait(); } } - // This presence must be send from a full JID. We use the resourcepart of this JID as nick, since the room may - // performed roomnick rewriting + // This presence must be sent from a full JID. We use the resourcepart of this JID as nick, since the room may + // have performed roomnick rewriting Resourcepart receivedNickname = reflectedSelfPresence.getFrom().getResourceOrThrow(); setNickname(receivedNickname); @@ -481,7 +481,7 @@ public class MultiUserChat { * @throws NotConnectedException if the XMPP connection is not connected. * @throws MucAlreadyJoinedException if already joined the Multi-User Chat.7y * @throws MissingMucCreationAcknowledgeException if there MUC creation was not acknowledged by the service. - * @throws NotAMucServiceException if the entity is not a MUC serivce. + * @throws NotAMucServiceException if the entity is not a MUC service. */ public synchronized MucCreateConfigFormHandle create(Resourcepart nickname) throws NoResponseException, XMPPErrorException, InterruptedException, MucAlreadyJoinedException, @@ -515,7 +515,7 @@ public class MultiUserChat { * @throws InterruptedException if the calling thread was interrupted. * @throws NotConnectedException if the XMPP connection is not connected. * @throws MucAlreadyJoinedException if already joined the Multi-User Chat.7y - * @throws NotAMucServiceException if the entity is not a MUC serivce. + * @throws NotAMucServiceException if the entity is not a MUC service. */ public synchronized MucCreateConfigFormHandle createOrJoin(Resourcepart nickname) throws NoResponseException, XMPPErrorException, InterruptedException, MucAlreadyJoinedException, NotConnectedException, NotAMucServiceException { @@ -537,7 +537,7 @@ public class MultiUserChat { * @throws InterruptedException if the calling thread was interrupted. * @throws MucAlreadyJoinedException if the MUC is already joined * @throws NotConnectedException if the XMPP connection is not connected. - * @throws NotAMucServiceException if the entity is not a MUC serivce. + * @throws NotAMucServiceException if the entity is not a MUC service. */ public synchronized MucCreateConfigFormHandle createOrJoin(MucEnterConfiguration mucEnterConfiguration) throws NoResponseException, XMPPErrorException, InterruptedException, MucAlreadyJoinedException, NotConnectedException, NotAMucServiceException { @@ -610,7 +610,7 @@ public class MultiUserChat { * @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. - * @throws NotAMucServiceException if the entity is not a MUC serivce. + * @throws NotAMucServiceException if the entity is not a MUC service. */ public MucCreateConfigFormHandle createOrJoinIfNecessary(Resourcepart nickname, String password) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException, NotAMucServiceException { @@ -646,7 +646,7 @@ public class MultiUserChat { * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. - * @throws NotAMucServiceException if the entity is not a MUC serivce. + * @throws NotAMucServiceException if the entity is not a MUC service. */ public Presence join(Resourcepart nickname) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException, NotAMucServiceException { @@ -676,7 +676,7 @@ public class MultiUserChat { * @throws InterruptedException if the calling thread was interrupted. * @throws NotConnectedException if the XMPP connection is not connected. * @throws NoResponseException if there was no response from the server. - * @throws NotAMucServiceException if the entity is not a MUC serivce. + * @throws NotAMucServiceException if the entity is not a MUC service. */ public void join(Resourcepart nickname, String password) throws XMPPErrorException, InterruptedException, NoResponseException, NotConnectedException, NotAMucServiceException { MucEnterConfiguration.Builder builder = getEnterConfigurationBuilder(nickname).withPassword( @@ -709,7 +709,7 @@ public class MultiUserChat { * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. - * @throws NotAMucServiceException if the entity is not a MUC serivce. + * @throws NotAMucServiceException if the entity is not a MUC service. */ public synchronized Presence join(MucEnterConfiguration mucEnterConfiguration) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException, NotAMucServiceException { @@ -833,9 +833,9 @@ public class MultiUserChat { /** * Returns the room's configuration form that the room's owner can use. * The configuration form allows to set the room's language, - * enable logging, specify room's type, etc.. + * enable logging, specify room's type, etc. * - * @return the Form that contains the fields to complete together with the instrucions or + * @return the Form that contains the fields to complete together with the instructions or * null if no configuration is possible. * @throws XMPPErrorException if an error occurs asking the configuration form for the room. * @throws NoResponseException if there was no response from the server. @@ -889,7 +889,7 @@ public class MultiUserChat { * error to the user (error code 405). * * @return the registration Form that contains the fields to complete together with the - * instrucions or null if no registration is possible. + * instructions or null if no registration is possible. * @throws XMPPErrorException if an error occurs asking the registration form for the room or a * 405 error if the user is not allowed to register with the room. * @throws NoResponseException if there was no response from the server. @@ -1598,7 +1598,7 @@ public class MultiUserChat { /** * Grants moderator privileges to participants or visitors. Room administrators may grant * moderator privileges. A moderator is allowed to kick users, grant and revoke voice, invite - * other users, modify room's subject plus all the partcipants privileges. + * other users, modify room's subject plus all the participant privileges. * * @param nicknames the nicknames of the occupants to grant moderator privileges. * @throws XMPPErrorException if an error occurs granting moderator privileges to a user. @@ -1613,7 +1613,7 @@ public class MultiUserChat { /** * Grants moderator privileges to a participant or visitor. Room administrators may grant * moderator privileges. A moderator is allowed to kick users, grant and revoke voice, invite - * other users, modify room's subject plus all the partcipants privileges. + * other users, modify room's subject plus all the participant privileges. * * @param nickname the nickname of the occupant to grant moderator privileges. * @throws XMPPErrorException if an error occurs granting moderator privileges to a user. @@ -2171,7 +2171,7 @@ public class MultiUserChat { /** * Polls for and returns the next message, or null if there isn't * a message immediately available. This method provides significantly different - * functionalty than the {@link #nextMessage()} method since it's non-blocking. + * functionality than the {@link #nextMessage()} method since it's non-blocking. * In other words, the method call will always return immediately, whereas the * nextMessage method will return only when a message is available (or after * a specific timeout). @@ -2204,7 +2204,7 @@ public class MultiUserChat { /** * Returns the next available message in the chat. The method call will block - * (not return) until a stanza is available or the timeout has elapased. + * (not return) until a stanza is available or the timeout has elapsed. * If the timeout elapses without a result, null will be returned. * * @param timeout the maximum amount of time to wait for the next message. diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java index 9d031a8bd..e8012406f 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java @@ -298,7 +298,7 @@ public final class MultiUserChatManager extends Manager { * {@link MultiUserChat#join(org.jxmpp.jid.parts.Resourcepart) join} the chat room. On some server implementations, the room will not be * created until the first person joins it. *

    - * Most XMPP servers use a sub-domain for the chat service (eg chat.example.com for the XMPP server example.com). + * Most XMPP servers use a sub-domain for the chat service (e.g.chat.example.com for the XMPP server example.com). * You must ensure that the room address you're trying to connect to includes the proper chat sub-domain. *

    * @@ -481,7 +481,7 @@ public final class MultiUserChatManager extends Manager { * @throws NoResponseException if there was no response from the remote entity. * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. - * @throws NotAMucServiceException if the entity is not a MUC serivce. + * @throws NotAMucServiceException if the entity is not a MUC service. * @since 4.3.1 */ public Map getRoomsHostedBy(DomainBareJid serviceName) throws NoResponseException, XMPPErrorException, diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/ParticipantStatusListener.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/ParticipantStatusListener.java index 8a376ca36..58454d6e9 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/ParticipantStatusListener.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/ParticipantStatusListener.java @@ -129,7 +129,7 @@ public interface ParticipantStatusListener { /** * Called when an administrator grants moderator privileges to a user. This means that the user * will be able to kick users, grant and revoke voice, invite other users, modify room's - * subject plus all the partcipants privileges. + * subject plus all the participant privileges. * * @param participant the participant that was granted moderator privileges in the room * (e.g. room@conference.jabber.org/nick). @@ -140,7 +140,7 @@ public interface ParticipantStatusListener { /** * Called when an administrator revokes moderator privileges from a user. This means that the * user will no longer be able to kick users, grant and revoke voice, invite other users, - * modify room's subject plus all the partcipants privileges. + * modify room's subject plus all the participant privileges. * * @param participant the participant that was revoked moderator privileges in the room * (e.g. room@conference.jabber.org/nick). diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/RoomInfo.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/RoomInfo.java index d321903dd..b43e33ae9 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/RoomInfo.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/RoomInfo.java @@ -77,7 +77,7 @@ public class RoomInfo { */ private final boolean moderated; /** - * Every presence stanza can include the JID of every occupant unless the owner deactives this + * Every presence stanza can include the JID of every occupant unless the owner deactivates this * configuration. */ private final boolean nonanonymous; @@ -250,7 +250,7 @@ public class RoomInfo { /** * Returns the room name. *

    - * The name returnd here was provided as value of the name attribute + * The name returned here was provided as value of the name attribute * of the returned identity within the disco#info result. *

    * @@ -324,9 +324,9 @@ public class RoomInfo { } /** - * Returns true if users musy provide a valid password in order to join the room. + * Returns true if users must provide a valid password in order to join the room. * - * @return true if users musy provide a valid password in order to join the room. + * @return true if users must provide a valid password in order to join the room. */ public boolean isPasswordProtected() { return passwordProtected; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/UserStatusListener.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/UserStatusListener.java index b8d9db944..93cf585fe 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/UserStatusListener.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/UserStatusListener.java @@ -39,7 +39,7 @@ public interface UserStatusListener { /** * Called when a moderator kicked your user from the room. This means that you are no longer - * participanting in the room. + * participating in the room. * * @param actor the moderator that kicked your user from the room (e.g. user@host.org). * @param reason the reason provided by the actor to kick you from the room. @@ -106,7 +106,7 @@ public interface UserStatusListener { /** * Called when an administrator grants moderator privileges to your user. This means that you * will be able to kick users, grant and revoke voice, invite other users, modify room's - * subject plus all the partcipants privileges. + * subject plus all the participant privileges. * */ default void moderatorGranted() { @@ -115,7 +115,7 @@ public interface UserStatusListener { /** * Called when an administrator revokes moderator privileges from your user. This means that * you will no longer be able to kick users, grant and revoke voice, invite other users, - * modify room's subject plus all the partcipants privileges. + * modify room's subject plus all the participant privileges. * */ default void moderatorRevoked() { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/package-info.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/package-info.java index 5adaa5a6f..78866dd6a 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/package-info.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/package-info.java @@ -534,7 +534,7 @@ *

    *

    Usage

    *

    - * In order to grant membership to a room, administrator privileges or owner priveliges just send + * In order to grant membership to a room, administrator privileges or owner privileges just send * **grantMembership(String jid)**, **grantAdmin(String jid)** or **grantOwnership(String jid)** to _**MultiUserChat**_ * respectively. Use **revokeMembership(String jid)**, **revokeAdmin(String jid)** or revokeOwnership(String jid)** to * revoke the membership to a room, administrator privileges or owner priveliges respectively. diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/nick/packet/Nick.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/nick/packet/Nick.java index bc1bd04b4..3ea4d3e1d 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/nick/packet/Nick.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/nick/packet/Nick.java @@ -35,7 +35,7 @@ public class Nick implements ExtensionElement { public static final QName QNAME = new QName(NAMESPACE, "nick"); /** - * Deprected, do not use. + * Deprecated, do not use. * * @deprecated use {@link #QNAME} instead. */ diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/PepManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/PepManager.java index 404da53fb..7eaad0db4 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/PepManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/PepManager.java @@ -288,7 +288,7 @@ public final class PepManager extends Manager { */ public LeafNode publish(String nodeId, Item item) throws NotConnectedException, InterruptedException, NoResponseException, XMPPErrorException, NotALeafNodeException { - // PEP nodes are auto created if not existent. Hence Use PubSubManager.tryToPublishAndPossibleAutoCreate() here. + // PEP nodes are auto created if not existent. Hence, use PubSubManager.tryToPublishAndPossibleAutoCreate() here. return pepPubSubManager.tryToPublishAndPossibleAutoCreate(nodeId, item); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java index b7b0f1dcd..fc39376b3 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java @@ -150,11 +150,11 @@ public final class PingManager extends Manager { // We may received an error response from an intermediate service returning an error like // 'remote-server-not-found' or 'remote-server-timeout' to us (which would fake the 'from' address, - // see RFC 6120 § 8.3.1 2.). Or the recipient could became unavailable. + // see RFC 6120 § 8.3.1 2.). Or the recipient could become unavailable. // Sticking with the current rules of RFC 6120/6121, it is undecidable at this point whether we received an // error response from the pinged entity or not. This is because a service-unavailable error condition is - // *required* (as per the RFCs) to be send back in both relevant cases: + // *required* (as per the RFCs) to be sent back in both relevant cases: // 1. When the receiving entity is unaware of the IQ request type. RFC 6120 § 8.4.: // "If an intended recipient receives an IQ stanza of type "get" or // "set" containing a child element qualified by a namespace it does @@ -244,7 +244,7 @@ public final class PingManager extends Manager { } /** - * Same as calling {@link #ping(Jid, long)} with the defaultpacket reply + * Same as calling {@link #ping(Jid, long)} with the default packet reply * timeout. * * @param jid The id of the entity the ping is being sent to diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/package-info.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/package-info.java index 38a4c93c3..bfdc39d03 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/package-info.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/package-info.java @@ -156,7 +156,7 @@ *

    * In order to handle privacy changes, clients SHOULD listen manager’s updates. When a list is changed the manager * notifies every added listener. Listeners MUST implement the PrivacyListListener interface. Clients may - * need to react when a privacy list is modified. The PrivacyListManager lets you add listerners that will + * need to react when a privacy list is modified. The PrivacyListManager lets you add listeners that will * be notified when a list has been changed. Listeners should implement the PrivacyListListener interface. *

    *

    diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/packet/PrivacyItem.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/packet/PrivacyItem.java index c977fdaf3..a80276e5b 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/packet/PrivacyItem.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/packet/PrivacyItem.java @@ -171,7 +171,7 @@ public class PrivacyItem { } /** - * Sets wheather the receiver allows or denies incoming messages or not. + * Sets whether the receiver allows or denies incoming messages or not. * * @param filterMessage indicates if the receiver allows or denies incoming messages or not. */ diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java index cbe9c10cb..6744c5713 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java @@ -263,7 +263,7 @@ public final class PubSubManager extends Manager { DataForm submitForm = config.getDataFormToSubmit(); request.addExtension(new FormNode(FormNodeType.CONFIGURE, submitForm)); NodeType nodeType = config.getNodeType(); - // Note that some implementations do to have the pubsub#node_type field in their defauilt configuration, + // Note that some implementations do to have the pubsub#node_type field in their default configuration, // which I believe to be a bug. However, since PubSub specifies the default node type to be 'leaf' we assume // leaf if the field does not exist. isLeafNode = nodeType == null || nodeType == NodeType.leaf; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/SimplePayload.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/SimplePayload.java index 200be7f4b..730c4c4c8 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/SimplePayload.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/SimplePayload.java @@ -66,7 +66,7 @@ public class SimplePayload implements XmlElement { * @param elementName The root element name (of the payload) * @param namespace The namespace of the payload, null if there is none * @param xmlPayload The payload data - * @deprecated use {@link #SimplePayload(String)} insteas. + * @deprecated use {@link #SimplePayload(String)} instead. */ // TODO: Remove in Smack 4.5 @Deprecated diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/search/ReportedData.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/search/ReportedData.java index 36853164b..ac2cec39d 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/search/ReportedData.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/search/ReportedData.java @@ -150,7 +150,7 @@ public class ReportedData { /** * Creates a new column with the specified definition. * - * @param label the columns's label. + * @param label the column's label. * @param variable the variable name of the column. * @param type the format for the returned data. */ diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/packet/VCard.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/packet/VCard.java index 4f4d74a19..4d6f18ecf 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/packet/VCard.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/packet/VCard.java @@ -122,7 +122,7 @@ public final class VCard extends IQ { private String photoBinval; /** - * Such as DESC ROLE GEO etc.. see XEP-0054 + * Such as DESC ROLE GEO etc. see XEP-0054 */ private final Map otherSimpleFields = new HashMap<>(); @@ -575,7 +575,7 @@ public final class VCard extends IQ { * Load VCard information for a given user. XMPPConnection should be authenticated and not anonymous. * * @param connection connection. - * @param user user whos information we want to load. + * @param user user whose information we want to load. * * @throws XMPPErrorException if there was an XMPP error returned. * @throws NoResponseException if there was no response from the server. diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/BooleanFormField.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/BooleanFormField.java index 6681e6408..756c14b52 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/BooleanFormField.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/BooleanFormField.java @@ -36,7 +36,7 @@ public class BooleanFormField extends SingleValueFormField { } /** - * Get the value of the booelan field. Note that, if no explicit boolean value is provided, in the form of "true", + * Get the value of the boolean field. Note that, if no explicit boolean value is provided, in the form of "true", * "false", "0", or "1", then the default value of a boolean field is false, according to * XEP-0004 § 3.3. * diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xhtmlim/package-info.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xhtmlim/package-info.java index 7054e0f22..7ebb8cee9 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xhtmlim/package-info.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xhtmlim/package-info.java @@ -152,7 +152,7 @@ * Before you start to send XHTML messages to a user you should discover if the user supports XHTML messages. There are * two ways to achieve the discovery, explicitly and implicitly. Explicit is when you first try to discover if the user * supports XHTML before sending any XHTML message. Implicit is when you send XHTML messages without first discovering - * if the conversation partner's client supports XHTML and depenging on the answer (normal message or XHTML message) you + * if the conversation partner's client supports XHTML and depending on the answer (normal message or XHTML message) you * find out if the user supports XHTML messages or not. This section explains how to explicitly discover for XHTML * support. *

    diff --git a/smack-im/src/main/java/org/jivesoftware/smack/chat/Chat.java b/smack-im/src/main/java/org/jivesoftware/smack/chat/Chat.java index c57bc5e34..a00871964 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/chat/Chat.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/chat/Chat.java @@ -79,7 +79,7 @@ public class Chat { /** * Returns the name of the user the chat is with. * - * @return the name of the user the chat is occuring with. + * @return the name of the user the chat is occurring with. */ public EntityJid getParticipant() { return participant; diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java index c640edfdc..4b38ef567 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java @@ -118,8 +118,8 @@ import org.jxmpp.util.cache.LruCache; * Every entry in the roster has presence associated with it. The * {@link #getPresence(BareJid)} method will return a Presence object with the * user's presence or `null` if the user is not online or you are not subscribed - * to the user's presence. _Note:_ Presence subscription is nnot tied to the - * user being on the roster, and vice versa: You could be subscriped to a remote + * to the user's presence. _Note:_ Presence subscription is not tied to the + * user being on the roster, and vice versa: You could be subscribed to a remote * users presence without the user in your roster, and a remote user can be in * your roster without any presence subscription relation. *

    @@ -242,13 +242,13 @@ public final class Roster extends Manager { private static boolean rosterLoadedAtLoginDefault = true; /** - * The default subscription processing mode to use when a Roster is created. By default + * The default subscription processing mode to use when a Roster is created. By default, * all subscription requests are automatically rejected. */ private static SubscriptionMode defaultSubscriptionMode = SubscriptionMode.reject_all; /** - * The initial maximum size of the map holding presence information of entities without an Roster entry. Currently + * The initial maximum size of the map holding presence information of entities without a Roster entry. Currently * {@value #INITIAL_DEFAULT_NON_ROSTER_PRESENCE_MAP_SIZE}. */ public static final int INITIAL_DEFAULT_NON_ROSTER_PRESENCE_MAP_SIZE = 1024; @@ -285,7 +285,7 @@ public final class Roster extends Manager { private final Map> presenceMap = new ConcurrentHashMap<>(); /** - * Like {@link presenceMap} but for presences of entities not in our Roster. + * Like {@link #presenceMap} but for presences of entities not in our Roster. */ // TODO Ideally we want here to use a LRU cache like Map which will evict all superfluous items // if their maximum size is lowered below the current item count. LruCache does not provide @@ -299,7 +299,7 @@ public final class Roster extends Manager { private final Set rosterLoadedListeners = new LinkedHashSet<>(); /** - * Mutually exclude roster listener invocation and changing the {@link entries} map. Also used + * Mutually exclude roster listener invocation and changing the {@link #entries} map. Also used * to synchronize access to either the roster listeners or the entries map. */ private final Object rosterListenersAndEntriesLock = new Object(); @@ -439,7 +439,7 @@ public final class Roster extends Manager { return; } - // Ensure that all available presences received so far in a eventually existing previous session are + // Ensure that all available presences received so far in an eventually existing previous session are // marked 'offline'. setOfflinePresencesAndResetLoaded(); @@ -760,7 +760,7 @@ public final class Roster extends Manager { * * @param user the user. (e.g. johndoe@jabber.org) * @param name the nickname of the user. - * @param groups the list of group names the entry will belong to, or null if the + * @param groups the list of group names the entry will belong to, or null if * the roster entry won't belong to a group. * @throws NoResponseException if there was no response from the server. * @throws XMPPErrorException if an XMPP exception occurs. @@ -818,7 +818,7 @@ public final class Roster extends Manager { * * @param jid the XMPP address of the contact (e.g. johndoe@jabber.org) * @param name the nickname of the user. - * @param groups the list of group names the entry will belong to, or null if the + * @param groups the list of group names the entry will belong to, or null if * the roster entry won't belong to a group. * @throws NoResponseException if there was no response from the server. * @throws XMPPErrorException if an XMPP exception occurs. @@ -839,7 +839,7 @@ public final class Roster extends Manager { * * @param user the user. (e.g. johndoe@jabber.org) * @param name the nickname of the user. - * @param groups the list of group names the entry will belong to, or null if the + * @param groups the list of group names the entry will belong to, or null if * the roster entry won't belong to a group. * @throws NoResponseException if there was no response from the server. * @throws XMPPErrorException if an XMPP exception occurs. @@ -1042,7 +1042,7 @@ public final class Roster extends Manager { * Returns the roster entry associated with the given XMPP address or * null if the user is not an entry in the roster. * - * @param jid the XMPP address of the user (eg "jsmith@example.com"). The address could be + * @param jid the XMPP address of the user (e.g."jsmith@example.com"). The address could be * in any valid format (e.g. "domain/resource", "user@domain" or "user@domain/resource"). * @return the roster entry or null if it does not exist. */ @@ -1056,7 +1056,7 @@ public final class Roster extends Manager { /** * Returns true if the specified XMPP address is an entry in the roster. * - * @param jid the XMPP address of the user (eg "jsmith@example.com"). The + * @param jid the XMPP address of the user (e.g."jsmith@example.com"). The * address must be a bare JID e.g. "domain/resource" or * "user@domain". * @return true if the XMPP address is an entry in the roster. @@ -1118,11 +1118,11 @@ public final class Roster extends Manager { * {@link RosterListener}. *

    * - * @param jid the XMPP address of the user (eg "jsmith@example.com"). The + * @param jid the XMPP address of the user (e.g."jsmith@example.com"). The * address must be a bare JID e.g. "domain/resource" or * "user@domain". * @return the user's current presence, or unavailable presence if the user is offline - * or if no presence information is available.. + * or if no presence information is available. */ public Presence getPresence(BareJid jid) { Map userPresences = getPresencesInternal(jid); diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterEntry.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterEntry.java index 8a13fda90..0360f892b 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterEntry.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterEntry.java @@ -108,7 +108,7 @@ public final class RosterEntry extends Manager { packet.setType(IQ.Type.set); // Create a new roster item with the current RosterEntry and the *new* name. Note that we can't set the name of - // RosterEntry right away, as otherwise the updated event wont get fired, because equalsDeep would return true. + // RosterEntry right away, as otherwise the updated event won't get fired, because equalsDeep would return true. packet.addRosterItem(toRosterItem(this, name)); connection().sendIqRequestAndWaitForResponse(packet); @@ -136,7 +136,7 @@ public final class RosterEntry extends Manager { } /** - * Returns an copied list of the roster groups that this entry belongs to. + * Returns a copied list of the roster groups that this entry belongs to. * * @return an iterator for the groups this entry belongs to. */ @@ -306,7 +306,7 @@ public final class RosterEntry extends Manager { * * @param entry the roster entry. * @param name the name of the roster item. - * @param includeAskAttribute whether or not to include the 'ask' attribute. + * @param includeAskAttribute whether to include the 'ask' attribute. * @return the roster item. */ private static RosterPacket.Item toRosterItem(RosterEntry entry, String name, boolean includeAskAttribute) { diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterGroup.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterGroup.java index f8718fcbb..d6467dd83 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterGroup.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterGroup.java @@ -116,7 +116,7 @@ public class RosterGroup extends Manager { * Returns the roster entry associated with the given XMPP address or * null if the user is not an entry in the group. * - * @param user the XMPP address of the user (eg "jsmith@example.com"). + * @param user the XMPP address of the user (e.g."jsmith@example.com"). * @return the roster entry or null if it does not exist in the group. */ public RosterEntry getEntry(Jid user) { diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java index 8afe9f9e4..a0f658977 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java @@ -100,8 +100,8 @@ public class XmppConnectionStressTest { for (int c = 0; c < payloadChunkCount; c++) { int payloadChunkSize = random.nextInt(configuration.maxPayloadChunkSize) + 1; - String payloadCunk = StringUtils.randomString(payloadChunkSize, random); - JivePropertiesManager.addProperty(messageBuilder, "payload-chunk-" + c, payloadCunk); + String payloadChunk = StringUtils.randomString(payloadChunkSize, random); + JivePropertiesManager.addProperty(messageBuilder, "payload-chunk-" + c, payloadChunk); } JivePropertiesManager.addProperty(messageBuilder, MESSAGE_NUMBER_PROPERTY, i); @@ -184,7 +184,7 @@ public class XmppConnectionStressTest { Exception exception = new Exception(exceptionMessage.toString()); receiveExceptions.put(connection, exception); // TODO: Current Smack design does not guarantee that the listener won't be invoked again. - // This is because the decission to invoke a sync listeners is done at a different place + // This is because the decision to invoke a sync listeners is done at a different place // then invoking the listener. connection.removeSyncStanzaListener(this); receivedSemaphore.release(); @@ -338,7 +338,7 @@ public class XmppConnectionStressTest { sb.append("Exceptions while sending and/or receiving."); if (!sendExceptions.isEmpty()) { - sb.append(" Send exxceptions: "); + sb.append(" Send exceptions: "); for (Map.Entry entry : sendExceptions.entrySet()) { sb.append(entry.getKey()).append(": ").append(entry.getValue()).append(';'); } diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java index 070974a67..dd0f7fcac 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java @@ -432,7 +432,7 @@ public class SmackIntegrationTestFramework { final Class[] parameterTypes = method.getParameterTypes(); if (parameterTypes.length > 0) { throw new IllegalStateException( - "SmackIntegrationTest annotaton on " + method + " that takes arguments "); + "SmackIntegrationTest annotation on " + method + " that takes arguments "); } break; case LowLevel: diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/XmppConnectionDescriptor.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/XmppConnectionDescriptor.java index 173407429..adcdcaa40 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/XmppConnectionDescriptor.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/XmppConnectionDescriptor.java @@ -155,7 +155,7 @@ public final class XmppConnectionDescriptor< return XmppConnectionDescriptor.buildWith(ModularXmppClientToServerConnection.class, ModularXmppClientToServerConnectionConfiguration.class, ModularXmppClientToServerConnectionConfiguration.Builder.class) .withNickname(nickname) - .applyExtraConfguration(cb -> { + .applyExtraConfiguration(cb -> { cb.removeAllModules(); ModularXmppClientToServerConnectionModuleDescriptor webSocketModuleDescriptor = XmppWebSocketTransportModuleDescriptor.getBuilder(cb) @@ -184,7 +184,13 @@ public final class XmppConnectionDescriptor< nickname = connectionClass.getSimpleName(); } + // TODO Remove in Smack 4.6 + @Deprecated // Replaced by applyExtraConfiguration(Consumer extraBuilder) public Builder applyExtraConfguration(Consumer extraBuilder) { + return applyExtraConfiguration(extraBuilder); + } + + public Builder applyExtraConfiguration(Consumer extraBuilder) { this.extraBuilder = extraBuilder; return this; } diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/XmppConnectionManager.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/XmppConnectionManager.java index 0653e5d14..3b2f21b60 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/XmppConnectionManager.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/XmppConnectionManager.java @@ -85,7 +85,7 @@ public class XmppConnectionManager { addConnectionDescriptor( XmppConnectionDescriptor.buildWith(ModularXmppClientToServerConnection.class, ModularXmppClientToServerConnectionConfiguration.class, ModularXmppClientToServerConnectionConfiguration.Builder.class) .withNickname("modular-nocompress") - .applyExtraConfguration(cb -> cb.removeModule(CompressionModuleDescriptor.class)) + .applyExtraConfiguration(cb -> cb.removeModule(CompressionModuleDescriptor.class)) .build() ); addConnectionDescriptor( diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java index 22ad207f5..84301a2f5 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/package-info.java @@ -145,7 +145,7 @@ * * * disabledSpecifications - * List of specificatinos for which to disable tests + * List of specifications for which to disable tests * * * defaultConnection diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/LoginIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/LoginIntegrationTest.java index 63704c2c2..1e75154a9 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/LoginIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/LoginIntegrationTest.java @@ -48,7 +48,7 @@ public class LoginIntegrationTest extends AbstractSmackLowLevelIntegrationTest { * @throws IOException if an I/O error occurred. * @throws SmackException if Smack detected an exceptional situation. * @throws NoSuchAlgorithmException if no such algorithm is available. - * @throws KeyManagementException if there was a key mangement error. + * @throws KeyManagementException if there was a key management error. */ @SmackIntegrationTest public void testInvalidLogin(UnconnectedConnectionSource unconnectedConnectionSource) throws SmackException, IOException, XMPPException, diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/LowLevelRosterIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/LowLevelRosterIntegrationTest.java index 045f06691..9f150bd7a 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/LowLevelRosterIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/LowLevelRosterIntegrationTest.java @@ -61,7 +61,7 @@ public class LowLevelRosterIntegrationTest extends AbstractSmackLowLevelIntegrat rosterOne.addPresenceEventListener(presenceEventListener); try { - // Disconnect conTwo, this should cause an 'unavailable' presence to be send from conTwo to + // Disconnect conTwo, this should cause an 'unavailable' presence to be sent from conTwo to // conOne. conTwo.disconnect(); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/AbstractMultiUserChatIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/AbstractMultiUserChatIntegrationTest.java index b13b4df6e..9465ef14a 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/AbstractMultiUserChatIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/AbstractMultiUserChatIntegrationTest.java @@ -185,7 +185,7 @@ public abstract class AbstractMultiUserChatIntegrationTest extends AbstractSmack *

    From XEP-0045 § 10.1.3:

    *
    * Note: The _whois configuration option specifies whether the room is non-anonymous (a value of "anyone"), - * semi-anonymous (a value of "moderators"), or fully anonmyous (a value of "none", not shown here). + * semi-anonymous (a value of "moderators"), or fully anonymous (a value of "none", not shown here). *
    */ static void createNonAnonymousMuc(MultiUserChat muc, Resourcepart resourceName) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, InterruptedException, MultiUserChatException.MucAlreadyJoinedException, SmackException.NotConnectedException, MultiUserChatException.MissingMucCreationAcknowledgeException, MultiUserChatException.NotAMucServiceException { @@ -202,7 +202,7 @@ public abstract class AbstractMultiUserChatIntegrationTest extends AbstractSmack *

    From XEP-0045 § 10.1.3:

    *
    * Note: The _whois configuration option specifies whether the room is non-anonymous (a value of "anyone"), - * semi-anonymous (a value of "moderators"), or fully anonmyous (a value of "none", not shown here). + * semi-anonymous (a value of "moderators"), or fully anonymous (a value of "none", not shown here). *
    */ static void createSemiAnonymousMuc(MultiUserChat muc, Resourcepart resourceName) throws SmackException.NoResponseException, XMPPException.XMPPErrorException, InterruptedException, MultiUserChatException.MucAlreadyJoinedException, SmackException.NotConnectedException, MultiUserChatException.MissingMucCreationAcknowledgeException, MultiUserChatException.NotAMucServiceException { diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java index 9c88f47fe..56c8a6dbb 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatRolesAffiliationsPrivilegesIntegrationTest.java @@ -219,7 +219,7 @@ public class MultiUserChatRolesAffiliationsPrivilegesIntegrationTest extends Abs } /** - * Asserts that a user in an unmoderated room who undergoes an afilliation change receives that change as a presence update. + * Asserts that a user in an unmoderated room who undergoes an affiliation change receives that change as a presence update. * * @throws Exception when errors occur */ diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/pubsub/PubSubIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/pubsub/PubSubIntegrationTest.java index 1b9954a03..d3f990a4a 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/pubsub/PubSubIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/pubsub/PubSubIntegrationTest.java @@ -113,7 +113,7 @@ public class PubSubIntegrationTest extends AbstractSmackIntegrationTest { // Add a dummy payload. If there is no payload, but just an item ID, then ejabberd will *not* return an error, // which I believe to be non-compliant behavior (although, granted, the XEP is not very clear about this). A user // which sends an empty item with ID to an node that is configured to be notification-only and transient probably - // does something wrong, as the item's ID will never appear anywhere. Hence it would be nice if the user would be + // does something wrong, as the item's ID will never appear anywhere. Hence, it would be nice if the user would be // made aware of this issue by returning an error. Sadly ejabberd does not do so. // See also https://github.com/processone/ejabberd/issues/2864#issuecomment-500741915 final StandardExtensionElement dummyPayload = StandardExtensionElement.builder("dummy-payload", diff --git a/smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/SmackIntegrationTestXmppConnectionManagerTest.java b/smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/SmackIntegrationTestXmppConnectionManagerTest.java index 7a2de6097..d8aa16015 100644 --- a/smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/SmackIntegrationTestXmppConnectionManagerTest.java +++ b/smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/SmackIntegrationTestXmppConnectionManagerTest.java @@ -43,7 +43,7 @@ public class SmackIntegrationTestXmppConnectionManagerTest { ModularXmppClientToServerConnection.class, ModularXmppClientToServerConnectionConfiguration.class, ModularXmppClientToServerConnectionConfiguration.Builder.class) - .applyExtraConfguration(b -> b.removeAllModules().addModule(XmppTcpTransportModuleDescriptor.class)) + .applyExtraConfiguration(b -> b.removeAllModules().addModule(XmppTcpTransportModuleDescriptor.class)) .build(); Configuration sinttestConfiguration = Configuration.builder().setService("example.org").build(); diff --git a/smack-java8-full/src/main/java/org/jivesoftware/smackx/SmackExtensions.java b/smack-java8-full/src/main/java/org/jivesoftware/smackx/SmackExtensions.java index 8ec3ad057..186562bba 100644 --- a/smack-java8-full/src/main/java/org/jivesoftware/smackx/SmackExtensions.java +++ b/smack-java8-full/src/main/java/org/jivesoftware/smackx/SmackExtensions.java @@ -18,7 +18,7 @@ package org.jivesoftware.smackx; /** * This is just a dummy class, please head over to {@link org.jivesoftware.smackx} for more information on Smack - * extensions. The dummy class causes javadoc generate the HTML for smackx.pacakge-info.java, which would otherwise be + * extensions. The dummy class causes javadoc generate the HTML for smackx.package-info.java, which would otherwise be * not generated, as org.jivesoftware.smackx is an empty package (see * JDK-4492654). */ diff --git a/smack-java8-full/src/main/java/org/jivesoftware/smackx/package-info.java b/smack-java8-full/src/main/java/org/jivesoftware/smackx/package-info.java index f499a6996..0769f65ba 100644 --- a/smack-java8-full/src/main/java/org/jivesoftware/smackx/package-info.java +++ b/smack-java8-full/src/main/java/org/jivesoftware/smackx/package-info.java @@ -71,7 +71,7 @@ * Extended Stanza Addressing * XEP-0033 * - * Allows to include headers in stanzas in order to specifiy multiple recipients or sub-addresses. + * Allows to include headers in stanzas in order to specify multiple recipients or sub-addresses. * * * Multi User Chat @@ -477,7 +477,7 @@ * Data Forms Geolocation Element * XEP-0350 * - * Allows to include XEP-0080 gelocation data in XEP-0004 data forms. + * Allows to include XEP-0080 geolocation data in XEP-0004 data forms. * * * Client State Indication diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleManager.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleManager.java index acd9a5796..f4ad1c0a8 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleManager.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleManager.java @@ -540,7 +540,7 @@ public class JingleManager implements JingleSessionListener { // } /** * When the session request is acceptable, this method should be invoked. It - * will create an JingleSession which allows the negotiation to procede. + * will create an JingleSession which allows the negotiation to proceed. * * @param request the remote request that is being accepted. * @return the session which manages the rest of the negotiation. @@ -560,7 +560,7 @@ public class JingleManager implements JingleSessionListener { /** * When the session request is acceptable, this method should be invoked. It - * will create an JingleSession which allows the negotiation to procede. + * will create an JingleSession which allows the negotiation to proceed. * This method use JingleMediaManager to select the supported Payload types. * * @param request the remote request that is being accepted. diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleNegotiator.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleNegotiator.java index 656faad25..d944679b8 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleNegotiator.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleNegotiator.java @@ -221,7 +221,7 @@ public abstract class JingleNegotiator { * <transport> * * This way, each segment of a Jingle stanza has a corresponding negotiator that know how to deal with that - * part of the Jingle packet. It also allows us to support Jingle packets of arbitraty complexity. + * part of the Jingle packet. It also allows us to support Jingle packets of arbitrary complexity. * * Each parent calls dispatchIncomingPacket for each of its children. The children then pass back a List of * results that will get sent when we reach the top level negotiator (JingleSession). diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleSession.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleSession.java index dabc962b0..cb141e837 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleSession.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleSession.java @@ -431,7 +431,7 @@ public final class JingleSession extends JingleNegotiator implements MediaReceiv /** * Complete and send a packet. Complete all the null fields in a Jingle - * reponse, using the session information we have. + * response, using the session information we have. * * @param jout * the Jingle stanza we want to complete and send @@ -445,7 +445,7 @@ public final class JingleSession extends JingleNegotiator implements MediaReceiv /** * Complete and send a packet. Complete all the null fields in a Jingle - * reponse, using the session information we have or some info from the + * response, using the session information we have or some info from the * incoming packet. * * @param iq The Jingle stanza we are responding to @@ -1097,7 +1097,7 @@ public final class JingleSession extends JingleNegotiator implements MediaReceiv } /** - * This is the starting point for intitiating a new session. + * This is the starting point for initiating a new session. * * @throws IllegalStateException if an illegal state was encountered * @throws SmackException if Smack detected an exceptional situation. diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleSessionState.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleSessionState.java index a1bc7263b..5a1f7660a 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleSessionState.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleSessionState.java @@ -56,7 +56,7 @@ public abstract class JingleSessionState { /** * Process an incoming Jingle Packet. - * When you look at the GoF State pattern this method roughly corresponds to example on p310: ProcessOctect() + * When you look at the GoF State pattern this method roughly corresponds to example on p310: ProcessOctet() * * @param session the jingle session. * @param jingle the jingle stanza. diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/listeners/CreatedJingleSessionListener.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/listeners/CreatedJingleSessionListener.java index 294e321cd..dda67f72e 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/listeners/CreatedJingleSessionListener.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/listeners/CreatedJingleSessionListener.java @@ -19,7 +19,7 @@ package org.jivesoftware.smackx.jingleold.listeners; import org.jivesoftware.smackx.jingleold.JingleSession; /** - * Inteface used to dispatch a event when a Jingle session is created. + * Interface used to dispatch an event when a Jingle session is created. * * @author Thiago Camargo */ diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/listeners/JingleSessionListener.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/listeners/JingleSessionListener.java index fb754e489..768cc42c9 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/listeners/JingleSessionListener.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/listeners/JingleSessionListener.java @@ -33,7 +33,7 @@ public interface JingleSessionListener extends JingleListener { * Notification that the session has been established. Arguments specify * the payload type and transport to use. * - * @param pt the Payload tyep to use + * @param pt the Payload type to use * @param remoteCandidate the remote candidate to use for connecting to the remote * service. * @param localCandidate the local candidate where we must listen for connections diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/media/JingleMediaSession.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/media/JingleMediaSession.java index 2956a265a..7df3c2f06 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/media/JingleMediaSession.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/media/JingleMediaSession.java @@ -25,7 +25,7 @@ import org.jivesoftware.smackx.jingleold.nat.TransportCandidate; /** * Public Abstract Class provides a clear interface between Media Session and Jingle API. *

    - * When a Jingle Session is fully stablished, we will have a Payload Type and two transport candidates defined for it. + * When a Jingle Session is fully established, we will have a Payload Type and two transport candidates defined for it. * Smack Jingle API don't implement Media Transmit and Receive methods. * But provides an interface to let the user implements it using another API. For instance: JMF. *

    @@ -153,7 +153,7 @@ public abstract class JingleMediaSession { public abstract void startReceive(); /** - * Set transmit activity. If the active is true, the instance should trasmit. + * Set transmit activity. If the active is true, the instance should transmit. * If it is set to false, the instance should pause transmit. * * @param active TODO javadoc me please @@ -173,7 +173,7 @@ public abstract class JingleMediaSession { /** * Called when new Media is received. * - * @param participant the particpant. + * @param participant the participant. */ public void mediaReceived(String participant) { for (MediaReceivedListener mediaReceivedListener : mediaReceivedListeners) { diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/media/PayloadType.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/media/PayloadType.java index c7dd7b8e0..08675d8b4 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/media/PayloadType.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/media/PayloadType.java @@ -322,7 +322,7 @@ public class PayloadType { } /** - * Set tha sampling clockRate for a playload type. + * Set tha sampling clockRate for a payload type. * * @param rate The sampling clockRate */ diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jmf/AudioChannel.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jmf/AudioChannel.java index 88cb3a649..61340f80e 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jmf/AudioChannel.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jmf/AudioChannel.java @@ -322,7 +322,7 @@ public class AudioChannel { String encoding = codecFormat.getEncoding(); if (encoding.equalsIgnoreCase(AudioFormat.GSM) || encoding.equalsIgnoreCase(AudioFormat.GSM_RTP)) { - return milliseconds * 4; // 1 byte per millisec + return milliseconds * 4; // 1 byte per millisecond } else if (encoding.equalsIgnoreCase(AudioFormat.ULAW) || encoding.equalsIgnoreCase(AudioFormat.ULAW_RTP)) { diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jspeex/AudioMediaSession.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jspeex/AudioMediaSession.java index 555836732..78495aa17 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jspeex/AudioMediaSession.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jspeex/AudioMediaSession.java @@ -71,7 +71,7 @@ public class AudioMediaSession extends JingleMediaSession implements MediaSessio * @throws NoProcessorException if there is no media processor. * @throws UnsupportedFormatException if the format is not supported. * @throws IOException if an I/O error occurred. - * @throws GeneralSecurityException if there was a geneeral security exception. + * @throws GeneralSecurityException if there was a general security exception. */ public static MediaSession createSession(String localhost, int localPort, String remoteHost, int remotePort, MediaSessionListener eventHandler, int quality, boolean secure, boolean micOn) throws NoProcessorException, UnsupportedFormatException, IOException, GeneralSecurityException { diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TransportNegotiator.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TransportNegotiator.java index 127a7364c..73bf75e9c 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TransportNegotiator.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TransportNegotiator.java @@ -95,7 +95,7 @@ public abstract class TransportNegotiator extends JingleNegotiator { * * @param session The Jingle session * @param transResolver The JingleTransportManager to use - * @param parentNegotiator the parent ngeotiator. + * @param parentNegotiator the parent negotiator. */ public TransportNegotiator(JingleSession session, TransportResolver transResolver, ContentNegotiator parentNegotiator) { super(session); diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TransportResolver.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TransportResolver.java index 75c1e2f71..b48545292 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TransportResolver.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TransportResolver.java @@ -236,7 +236,7 @@ public abstract class TransportResolver { } /** - * Trigger a event notifying the initialization of the resolution process. + * Trigger an event notifying the initialization of the resolution process. */ private void triggerResolveInit() { Iterator iter = getListenersList().iterator(); @@ -250,7 +250,7 @@ public abstract class TransportResolver { } /** - * Trigger a event notifying the obtainment of all the candidates. + * Trigger an event notifying the obtainment of all the candidates. */ private void triggerResolveEnd() { Iterator iter = getListenersList().iterator(); diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/provider/JingleTransportProvider.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/provider/JingleTransportProvider.java index 0edb7d887..b81e4f201 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/provider/JingleTransportProvider.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/provider/JingleTransportProvider.java @@ -88,7 +88,7 @@ public abstract class JingleTransportProvider extends ExtensionElementProvider listeners = new ArrayList<>(); private final Map> presenceMap = new HashMap<>(); // The roster is marked as initialized when at least a single roster packet - // has been recieved and processed. + // has been received and processed. boolean rosterInitialized = false; /** @@ -181,7 +181,7 @@ public class AgentRoster { /** * Returns true if the specified XMPP address is an agent in the workgroup. * - * @param jid the XMPP address of the agent (eg "jsmith@example.com"). The + * @param jid the XMPP address of the agent (e.g."jsmith@example.com"). The * address can be in any valid format (e.g. "domain/resource", "user@domain" * or "user@domain/resource"). * @return true if the XMPP address is an agent in the workgroup. @@ -208,7 +208,7 @@ public class AgentRoster { * @param user a fully qualified xmpp JID. The address could be in any valid format (e.g. * "domain/resource", "user@domain" or "user@domain/resource"). * @return the agent's current presence, or null if the agent is unavailable - * or if no presence information is available.. + * or if no presence information is available. */ public Presence getPresence(Jid user) { Jid key = getPresenceMapKey(user); diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/Offer.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/Offer.java index ece31d9c6..3449cd69b 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/Offer.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/Offer.java @@ -125,7 +125,7 @@ public class Offer { } /** - * The fully qualified name of the workgroup (eg support@example.com). + * The fully qualified name of the workgroup (e.g.support@example.com). * * @return the name of the workgroup. */ @@ -137,7 +137,7 @@ public class Offer { * The date when the offer will expire. The agent must {@link #accept()} * the offer before the expiration date or the offer will lapse and be * routed to another agent. Alternatively, the agent can {@link #reject()} - * the offer at any time if they don't wish to accept it.. + * the offer at any time if they don't wish to accept it. * * @return the date at which this offer expires. */ diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/OfferListener.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/OfferListener.java index 93de6bf8f..a33c6797b 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/OfferListener.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/OfferListener.java @@ -37,7 +37,7 @@ public interface OfferListener { void offerReceived (Offer request); /** - * The implementing class instance will be notified via this when the AgentSessino has received + * The implementing class instance will be notified via this when the AgentSession has received * a revocation of a previously extended offer. * * @param revokedOffer the RevokedOffer instance embodying the details of the revoked offer diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java index 59ad7c4dc..adb17a07e 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java @@ -91,7 +91,7 @@ public class Workgroup { /** * Creates a new workgroup instance using the specified workgroup JID - * (eg support@workgroup.example.com) and XMPP connection. The connection must have + * (e.g.support@workgroup.example.com) and XMPP connection. The connection must have * undergone a successful login before being used to construct an instance of * this class. * @@ -137,7 +137,7 @@ public class Workgroup { }); /** - * Internal handling of an invitation.Recieving an invitation removes the user from the queue. + * Internal handling of an invitation. Receiving an invitation removes the user from the queue. */ MultiUserChatManager.getInstanceFor(connection).addInvitationListener( new org.jivesoftware.smackx.muc.InvitationListener() { @@ -162,7 +162,7 @@ public class Workgroup { } /** - * Returns the name of this workgroup (eg support@example.com). + * Returns the name of this workgroup (e.g.support@example.com). * * @return the name of the workgroup. */ @@ -735,9 +735,9 @@ public class Workgroup { } /** - * Asks the workgroup for it's Properties. + * Asks the workgroup for its Properties. * - * @param jid the jid of the user who's information you would like the workgroup to retreive. + * @param jid the jid of the user whose information you would like the workgroup to retrieve. * @return the WorkgroupProperties for the specified workgroup. * @throws XMPPErrorException if there was an XMPP error returned. * @throws NoResponseException if there was no response from the remote entity. diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/xroster/RosterExchangeManager.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/xroster/RosterExchangeManager.java index baac6db8c..25461a3cd 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/xroster/RosterExchangeManager.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/xroster/RosterExchangeManager.java @@ -42,7 +42,7 @@ import org.jxmpp.jid.Jid; /** * - * Manages Roster exchanges. A RosterExchangeManager provides a high level access to send + * Manages Roster exchanges. A RosterExchangeManager provides high level access to send * rosters, roster groups and roster entries to XMPP clients. It also provides an easy way * to hook up custom logic when entries are received from another XMPP client through * RosterExchangeListeners. @@ -106,7 +106,7 @@ public class RosterExchangeManager { * Removes a listener from roster exchanges. The listener will be fired anytime roster * entries are received from remote XMPP clients. * - * @param rosterExchangeListener a roster exchange listener.. + * @param rosterExchangeListener a roster exchange listener. */ public void removeRosterListener(RosterExchangeListener rosterExchangeListener) { rosterExchangeListeners.remove(rosterExchangeListener); diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java index 82266bf2a..d8e768e01 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java @@ -893,7 +893,7 @@ public abstract class OmemoService *

    * The `setup()` method registers the service as a singleton. You can later access the instance by calling - * `SignalOmemoService.getInstace()`. The service can only be registered once. Subsequent calls will throw an + * `SignalOmemoService.getInstance()`. The service can only be registered once. Subsequent calls will throw an * {@link IllegalStateException}. *

    *

    2. Set an OmemoStore

    diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/util/OmemoMessageBuilder.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/util/OmemoMessageBuilder.java index 0810fe1d1..5144b4f02 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/util/OmemoMessageBuilder.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/util/OmemoMessageBuilder.java @@ -83,7 +83,7 @@ public class OmemoMessageBuilderEjabberd bug tracker about the issue diff --git a/smack-resolver-javax/src/main/java/org/jivesoftware/smack/util/dns/javax/JavaxResolver.java b/smack-resolver-javax/src/main/java/org/jivesoftware/smack/util/dns/javax/JavaxResolver.java index ea508f0fe..9e78b34b8 100644 --- a/smack-resolver-javax/src/main/java/org/jivesoftware/smack/util/dns/javax/JavaxResolver.java +++ b/smack-resolver-javax/src/main/java/org/jivesoftware/smack/util/dns/javax/JavaxResolver.java @@ -40,7 +40,7 @@ import org.minidns.record.SRV; /** * A DNS resolver (mostly for SRV records), which makes use of the API provided in the javax.* namespace. - * Note that using JavaxResovler requires applications using newer Java versions (at least 11) to declare a dependency on the "sun.jdk" module. + * Note that using JavaxResolver requires applications using newer Java versions (at least 11) to declare a dependency on the "sun.jdk" module. * * @author Florian Schmaus * diff --git a/smack-sasl-javax/src/main/java/org/jivesoftware/smack/sasl/javax/SASLExternalMechanism.java b/smack-sasl-javax/src/main/java/org/jivesoftware/smack/sasl/javax/SASLExternalMechanism.java index f0c409c49..fdc7822a8 100644 --- a/smack-sasl-javax/src/main/java/org/jivesoftware/smack/sasl/javax/SASLExternalMechanism.java +++ b/smack-sasl-javax/src/main/java/org/jivesoftware/smack/sasl/javax/SASLExternalMechanism.java @@ -24,7 +24,7 @@ package org.jivesoftware.smack.sasl.javax; * to the implementer to determine how to do this. Here is one method: * * Create a java keystore with your SSL certificate in it: - * keytool -genkey -alias username -dname "cn=username,ou=organizationalUnit,o=organizationaName,l=locality,s=state,c=country" + * keytool -genkey -alias username -dname "cn=username,ou=organizationalUnit,o=organizationalName,l=locality,s=state,c=country" * * Next, set the System Properties: *
      @@ -38,7 +38,7 @@ package org.jivesoftware.smack.sasl.javax; * simply provide the one in the keyStore. * * Also worth noting is the EXTERNAL mechanism in Smack is not enabled by default. - * To enable it, the implementer will need to call SASLAuthentication.supportSASLMechamism("EXTERNAL"); + * To enable it, the implementer will need to call SASLAuthentication.supportSASLMechanism("EXTERNAL"); * * @author Jay Kline */ diff --git a/smack-sasl-provided/src/main/java/org/jivesoftware/smack/sasl/provided/SASLDigestMD5Mechanism.java b/smack-sasl-provided/src/main/java/org/jivesoftware/smack/sasl/provided/SASLDigestMD5Mechanism.java index 2b1a89d0a..284ef767b 100644 --- a/smack-sasl-provided/src/main/java/org/jivesoftware/smack/sasl/provided/SASLDigestMD5Mechanism.java +++ b/smack-sasl-provided/src/main/java/org/jivesoftware/smack/sasl/provided/SASLDigestMD5Mechanism.java @@ -30,7 +30,7 @@ public class SASLDigestMD5Mechanism extends SASLMechanism { public static final String NAME = DIGESTMD5; - private static final String INITAL_NONCE = "00000001"; + private static final String INITIAL_NONCE = "00000001"; /** * The only 'qop' value supported by this implementation @@ -159,7 +159,7 @@ public class SASLDigestMD5Mechanism extends SASLMechanism { + ",realm=\"" + serviceName + '"' + ",nonce=\"" + nonce + '"' + ",cnonce=\"" + cnonce + '"' - + ",nc=" + INITAL_NONCE + + ",nc=" + INITIAL_NONCE + ",qop=auth" + ",digest-uri=\"" + digestUri + '"' + ",response=" + responseValue @@ -218,7 +218,7 @@ public class SASLDigestMD5Mechanism extends SASLMechanism { kd_argument.append(':'); kd_argument.append(nonce); kd_argument.append(':'); - kd_argument.append(INITAL_NONCE); + kd_argument.append(INITIAL_NONCE); kd_argument.append(':'); kd_argument.append(cnonce); kd_argument.append(':'); diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/sm/predicates/tcp/package-info.java b/smack-tcp/src/main/java/org/jivesoftware/smack/sm/predicates/tcp/package-info.java index 15e022848..d6f94b910 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/sm/predicates/tcp/package-info.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/sm/predicates/tcp/package-info.java @@ -16,6 +16,6 @@ */ /** - * XMPPTCPConnection Stream Managment Predicates. + * XMPPTCPConnection Stream Management Predicates. */ package org.jivesoftware.smack.sm.predicates.tcp; diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java index 38d2d3e55..87ce7c647 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java @@ -187,7 +187,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { private static boolean useSmResumptionDefault = true; /** - * The stream ID of the stream that is currently resumable, ie. the stream we hold the state + * The stream ID of the stream that is currently resumable, i.e. the stream we hold the state * for in {@link #clientHandledStanzasCount}, {@link #serverHandledStanzasCount} and * {@link #unacknowledgedStanzas}. */ @@ -203,7 +203,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { private Failed smResumptionFailed; /** - * Represents the state of stream magement. + * Represents the state of stream management. *

      * This boolean is marked volatile as it is read by various threads, including the reader thread via {@link #isSmEnabled()}. *

      @@ -1162,8 +1162,8 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { } catch (Exception e) { // Set running to false since this thread will exit here and notifyConnectionError() will wait until - // the reader and writer thread's 'running' value is false. Hence we need to set it to false before calling - // notifyConnetctionError() below, even though run() also sets it to false. Therefore, do not remove this. + // the reader and writer thread's 'running' value is false. Hence, we need to set it to false before calling + // notifyConnectionError() below, even though run() also sets it to false. Therefore, do not remove this. running = false; String ignoreReasonThread = null; @@ -1645,8 +1645,8 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { private void sendSmAcknowledgementInternal() throws NotConnectedException, InterruptedException { AckAnswer ackAnswer = new AckAnswer(clientHandledStanzasCount); // Do net put an ack to the queue if it has already been shutdown. Some servers, like ejabberd, like to request - // an ack even after we have send a stream close (and hance the queue was shutdown). If we would not check here, - // then the ack would dangle around in the queue, and be send on the next re-connection attempt even before the + // an ack even after we have sent a stream close (and hence the queue was shutdown). If we would not check here, + // then the ack would dangle around in the queue, and be sent on the next re-connection attempt even before the // stream open. packetWriter.queue.putIfNotShutdown(ackAnswer); } diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XmppTcpTransportModule.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XmppTcpTransportModule.java index bd194fcda..2feb626d3 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XmppTcpTransportModule.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XmppTcpTransportModule.java @@ -373,7 +373,7 @@ public class XmppTcpTransportModule extends ModularXmppClientToServerConnectionM } } - // It is ok if outpuFilterInputData is 'null' here, this is expected behavior. + // It is ok if outputFilterInputData is 'null' here, this is expected behavior. if (outputFilterInputData != null && outputFilterInputData.hasRemaining()) { filteredOutgoingBuffer = outputFilterInputData; } else { @@ -474,7 +474,7 @@ public class XmppTcpTransportModule extends ModularXmppClientToServerConnectionM // read() may return -1 if the input side of a socket is shut down. // Note that we do not call notifyConnectionError() here because the connection may be // cleanly shutdown which would also cause read() to return '-1. I assume that this socket - // will be selected again, on which read() would throw an IOException, which will be catched + // will be selected again, on which read() would throw an IOException, which will be caught // and invoke notifyConnectionError() (see a few lines above). /* IOException exception = new IOException("NIO read() returned " + bytesRead); @@ -633,7 +633,7 @@ public class XmppTcpTransportModule extends ModularXmppClientToServerConnectionM @Override protected void loadConnectionEndpoints(LookupConnectionEndpointsSuccess lookupConnectionEndpointsSuccess) { // The API contract stats that we will be given the instance we handed out with lookupConnectionEndpoints, - // which must be of type DiscoveredTcpEndpoints here. Hence if we can not cast it, then there is an internal + // which must be of type DiscoveredTcpEndpoints here. Hence, if we can not cast it, then there is an internal // Smack error. discoveredTcpEndpoints = (DiscoveredTcpEndpoints) lookupConnectionEndpointsSuccess; } @@ -711,7 +711,7 @@ public class XmppTcpTransportModule extends ModularXmppClientToServerConnectionM // Add OP_WRITE to the interested Ops, since we have now new things to write. Note that this may cause // multiple reactor threads to race to the channel selected callback in case we perform this right after - // a select() returned with this selection key in the selected-key set. Hence we use tryLock() in the + // a select() returned with this selection key in the selected-key set. Hence, we use tryLock() in the // channel selected callback to keep the invariant that only exactly one thread is performing the // callback. // Note that we need to perform setInterestedOps() *without* holding the channelSelectedCallbackLock, as @@ -776,7 +776,7 @@ public class XmppTcpTransportModule extends ModularXmppClientToServerConnectionM // TODO: It appears this should be done in a generic way. I'd assume we always // have to wait for stream features after the connection was established. If this is true then consider // moving this into State.AbstractTransport. But I am not yet 100% positive that this is the case for every - // transport. Hence keep it here for now. + // transport. Hence, keep it here for now. connectionInternal.newStreamOpenWaitForFeaturesSequence("stream features after initial connection"); return new TcpSocketConnectedResult(remoteAddress); @@ -1090,7 +1090,7 @@ public class XmppTcpTransportModule extends ModularXmppClientToServerConnectionM // A delegated task is asynchronously running. Take care of the remaining accumulatedData. addAsPendingInputData(accumulatedData); // Return here, as the async task created by handleHandshakeStatus will continue calling the - // cannelSelectedCallback. + // channelSelectedCallback. return null; case NEED_UNWRAP: continue; @@ -1114,7 +1114,7 @@ public class XmppTcpTransportModule extends ModularXmppClientToServerConnectionM switch (engineResultStatus) { case OK: // SSLEngine's unwrap() may not consume all bytes from the source buffer. If this is the case, then - // simply perform another unwrap until accumlatedData has no remaining bytes. + // simply perform another unwrap until accumulatedData has no remaining bytes. if (accumulatedData.hasRemaining()) { continue; } diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/rce/RemoteXmppTcpConnectionEndpoints.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/rce/RemoteXmppTcpConnectionEndpoints.java index 2b2514dbb..d46344d93 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/rce/RemoteXmppTcpConnectionEndpoints.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/rce/RemoteXmppTcpConnectionEndpoints.java @@ -169,7 +169,7 @@ public class RemoteXmppTcpConnectionEndpoints { * * @param domain the domain. * @param domainType the XMPP domain type, server or client. - * @param lookupFailures a list that will be populated with all failures that oocured during lookup. + * @param lookupFailures a list that will be populated with all failures that occurred during lookup. * @param dnssecMode the DNSSEC mode. * @param dnsResolver the DNS resolver to use. * @return a list of resolved host addresses for this domain. diff --git a/smack-websocket/src/main/java/org/jivesoftware/smack/websocket/WebSocketConnectionAttemptState.java b/smack-websocket/src/main/java/org/jivesoftware/smack/websocket/WebSocketConnectionAttemptState.java index 80f58ab42..222aafc65 100644 --- a/smack-websocket/src/main/java/org/jivesoftware/smack/websocket/WebSocketConnectionAttemptState.java +++ b/smack-websocket/src/main/java/org/jivesoftware/smack/websocket/WebSocketConnectionAttemptState.java @@ -51,7 +51,7 @@ public final class WebSocketConnectionAttemptState { /** * Establish a websocket connection with one of the discoveredRemoteConnectionEndpoints.
      * - * @return {@link AbstractWebSocket} with which connection is establised + * @return {@link AbstractWebSocket} with which connection is established * @throws InterruptedException if the calling thread was interrupted */ @SuppressWarnings({"incomplete-switch", "MissingCasesInEnumSwitch"}) diff --git a/smack-websocket/src/main/java/org/jivesoftware/smack/websocket/XmppWebSocketTransportModule.java b/smack-websocket/src/main/java/org/jivesoftware/smack/websocket/XmppWebSocketTransportModule.java index 435373203..55236858c 100644 --- a/smack-websocket/src/main/java/org/jivesoftware/smack/websocket/XmppWebSocketTransportModule.java +++ b/smack-websocket/src/main/java/org/jivesoftware/smack/websocket/XmppWebSocketTransportModule.java @@ -135,7 +135,7 @@ public final class XmppWebSocketTransportModule // TODO: It appears this should be done in a generic way. I'd assume we always // have to wait for stream features after the connection was established. But I - // am not yet 100% positive that this is the case for every transport. Hence keep it here for now(?). + // am not yet 100% positive that this is the case for every transport. Hence, keep it here for now(?). // See also similar comment in XmppTcpTransportModule. // Maybe move this into ConnectedButUnauthenticated state's transitionInto() method? That seems to be the // right place. @@ -157,7 +157,7 @@ public final class XmppWebSocketTransportModule final WebSocketRemoteConnectionEndpoint connectedEndpoint; public WebSocketConnectedResult(WebSocketRemoteConnectionEndpoint connectedEndpoint) { - super("WebSocket connection establised with endpoint: " + connectedEndpoint); + super("WebSocket connection established with endpoint: " + connectedEndpoint); this.connectedEndpoint = connectedEndpoint; } } diff --git a/smack-websocket/src/main/java/org/jivesoftware/smack/websocket/rce/WebSocketRemoteConnectionEndpointLookup.java b/smack-websocket/src/main/java/org/jivesoftware/smack/websocket/rce/WebSocketRemoteConnectionEndpointLookup.java index 347180f69..658814916 100644 --- a/smack-websocket/src/main/java/org/jivesoftware/smack/websocket/rce/WebSocketRemoteConnectionEndpointLookup.java +++ b/smack-websocket/src/main/java/org/jivesoftware/smack/websocket/rce/WebSocketRemoteConnectionEndpointLookup.java @@ -77,7 +77,7 @@ public final class WebSocketRemoteConnectionEndpointLookup { public Result(List lookupFailures) { // The list of endpoints needs to be mutable, because maybe a user supplied endpoint will be added to it. - // Hence we do not use Collections.emptyList() as argument for the discovered endpoints. + // Hence, we do not use Collections.emptyList() as argument for the discovered endpoints. this(new ArrayList<>(1), new ArrayList<>(1), lookupFailures); } @@ -99,7 +99,7 @@ public final class WebSocketRemoteConnectionEndpointLookup { // TODO: Remove the following methods since the fields are already public? Or make the fields private and use // the methods? I tend to remove the methods, as their method name is pretty long. But OTOH the fields reference - // mutable datastructes, which is uncommon to be public. + // mutable datastructures, which is uncommon to be public. public List getDiscoveredSecureRemoteConnectionEndpoints() { return discoveredSecureEndpoints; } diff --git a/smack-xmlparser/src/main/java/org/jivesoftware/smack/xml/XmlPullParser.java b/smack-xmlparser/src/main/java/org/jivesoftware/smack/xml/XmlPullParser.java index c49ac66ae..fd5a5acfc 100644 --- a/smack-xmlparser/src/main/java/org/jivesoftware/smack/xml/XmlPullParser.java +++ b/smack-xmlparser/src/main/java/org/jivesoftware/smack/xml/XmlPullParser.java @@ -110,7 +110,7 @@ public interface XmlPullParser { String getAttributeNamespace(int index); /** - * Returns the loacalpart of the attribute's name or null in case the index does not refer to an + * Returns the localpart of the attribute's name or null in case the index does not refer to an * attribute. * * @param index the attribute index. From b034e614d46d2fd4b102486fe5939d36c63ab2a2 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 12 Sep 2024 11:53:56 +0200 Subject: [PATCH 120/150] [github ci] Bump upload-artifact to v4 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cf69f7140..7d6507927 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -88,7 +88,7 @@ jobs: # Upload build artifacts - name: Upload build artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: smack-java-${{ matrix.java }} path: | From 6f0499b7f76ff9dcf10f091d1a9c016f4751d784 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 12 Sep 2024 14:36:20 +0200 Subject: [PATCH 121/150] [muc] Use BareJid for affiliation changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per XEP-0045 § 5.2 "Affiliations are granted, revoked, and maintained based on the user's bare JID, not the nick as with roles." Fixes SMACK-948 --- .../smackx/muc/MultiUserChat.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java index 9383d9e28..7ef1152d1 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java @@ -87,10 +87,10 @@ import org.jivesoftware.smackx.xdata.form.FillableForm; import org.jivesoftware.smackx.xdata.form.Form; import org.jivesoftware.smackx.xdata.packet.DataForm; +import org.jxmpp.jid.BareJid; import org.jxmpp.jid.DomainBareJid; import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityFullJid; -import org.jxmpp.jid.EntityJid; import org.jxmpp.jid.Jid; import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.parts.Resourcepart; @@ -1509,7 +1509,7 @@ public class MultiUserChat { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - public void banUsers(Collection jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { + public void banUsers(Collection jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { changeAffiliationByAdmin(jids, MUCAffiliation.outcast); } @@ -1529,7 +1529,7 @@ public class MultiUserChat { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - public void banUser(Jid jid, String reason) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { + public void banUser(BareJid jid, String reason) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { changeAffiliationByAdmin(jid, MUCAffiliation.outcast, reason); } @@ -1559,7 +1559,7 @@ public class MultiUserChat { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - public void grantMembership(Jid jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { + public void grantMembership(BareJid jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { changeAffiliationByAdmin(jid, MUCAffiliation.member, null); } @@ -1575,7 +1575,7 @@ public class MultiUserChat { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - public void revokeMembership(Collection jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { + public void revokeMembership(Collection jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { changeAffiliationByAdmin(jids, MUCAffiliation.none); } @@ -1591,7 +1591,7 @@ public class MultiUserChat { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - public void revokeMembership(Jid jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { + public void revokeMembership(BareJid jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { changeAffiliationByAdmin(jid, MUCAffiliation.none, null); } @@ -1669,7 +1669,7 @@ public class MultiUserChat { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - public void grantOwnership(Collection jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { + public void grantOwnership(Collection jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { changeAffiliationByAdmin(jids, MUCAffiliation.owner); } @@ -1685,7 +1685,7 @@ public class MultiUserChat { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - public void grantOwnership(Jid jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { + public void grantOwnership(BareJid jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { changeAffiliationByAdmin(jid, MUCAffiliation.owner, null); } @@ -1700,7 +1700,7 @@ public class MultiUserChat { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - public void revokeOwnership(Collection jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { + public void revokeOwnership(Collection jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { changeAffiliationByAdmin(jids, MUCAffiliation.admin); } @@ -1715,7 +1715,7 @@ public class MultiUserChat { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - public void revokeOwnership(Jid jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { + public void revokeOwnership(BareJid jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { changeAffiliationByAdmin(jid, MUCAffiliation.admin, null); } @@ -1730,7 +1730,7 @@ public class MultiUserChat { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - public void grantAdmin(Collection jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { + public void grantAdmin(Collection jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { changeAffiliationByAdmin(jids, MUCAffiliation.admin); } @@ -1746,7 +1746,7 @@ public class MultiUserChat { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - public void grantAdmin(Jid jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { + public void grantAdmin(BareJid jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { changeAffiliationByAdmin(jid, MUCAffiliation.admin); } @@ -1761,7 +1761,7 @@ public class MultiUserChat { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - public void revokeAdmin(Collection jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { + public void revokeAdmin(Collection jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { changeAffiliationByAdmin(jids, MUCAffiliation.admin); } @@ -1777,7 +1777,7 @@ public class MultiUserChat { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - public void revokeAdmin(EntityJid jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { + public void revokeAdmin(BareJid jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { changeAffiliationByAdmin(jid, MUCAffiliation.member); } From 4a101e2c993277917a1b533a4295980016bb2ee3 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 14 Sep 2024 21:34:47 +0200 Subject: [PATCH 122/150] Delete APIs scheduled for removal with Smack 4.5 --- .../smack/AbstractConnectionListener.java | 51 --- .../smack/AbstractXMPPConnection.java | 21 -- .../smack/ConnectionConfiguration.java | 41 +-- .../jivesoftware/smack/StanzaListener.java | 6 - .../jivesoftware/smack/XMPPConnection.java | 47 --- .../smack/packet/AbstractTextElement.java | 13 +- .../org/jivesoftware/smack/packet/IQ.java | 14 - .../jivesoftware/smack/packet/Message.java | 292 +----------------- .../smack/packet/MessageOrPresence.java | 5 - .../jivesoftware/smack/packet/Presence.java | 134 +------- .../org/jivesoftware/smack/packet/Stanza.java | 76 ----- .../jivesoftware/smack/util/NumberUtil.java | 14 +- .../jivesoftware/smack/util/ParserUtils.java | 17 +- .../jivesoftware/smack/util/StringUtils.java | 20 +- .../org/jivesoftware/smack/util/TLSUtils.java | 48 +-- .../smack/util/XmlStringBuilder.java | 16 +- .../smackx/muclight/MultiUserChatLight.java | 15 - .../smackx/sid/element/OriginIdElement.java | 22 -- .../smackx/bob/element/BoBIQ.java | 14 +- .../smackx/disco/ServiceDiscoveryManager.java | 36 +-- .../smackx/disco/packet/DiscoverInfo.java | 114 ------- .../jiveproperties/JivePropertiesManager.java | 21 +- .../muc/DefaultParticipantStatusListener.java | 98 ------ .../smackx/muc/DefaultUserStatusListener.java | 88 ------ .../smackx/muc/MucEnterConfiguration.java | 36 +-- .../smackx/muc/MultiUserChat.java | 63 +--- .../smackx/muc/MultiUserChatException.java | 4 +- .../smackx/muc/MultiUserChatManager.java | 18 +- .../jivesoftware/smackx/pep/PepManager.java | 28 +- .../smackx/pubsub/ItemDeleteEvent.java | 2 +- .../org/jivesoftware/smackx/pubsub/Node.java | 71 ----- .../smackx/pubsub/PubSubManager.java | 27 -- .../smackx/pubsub/SimplePayload.java | 21 -- .../smackx/vcardtemp/VCardManager.java | 2 +- .../jivesoftware/smackx/xdata/FormField.java | 19 +- .../smackx/xdata/packet/DataForm.java | 20 +- .../org/jivesoftware/smack/chat/Chat.java | 14 +- .../org/jivesoftware/smack/roster/Roster.java | 25 +- 38 files changed, 39 insertions(+), 1534 deletions(-) delete mode 100644 smack-core/src/main/java/org/jivesoftware/smack/AbstractConnectionListener.java delete mode 100644 smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultParticipantStatusListener.java delete mode 100644 smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultUserStatusListener.java diff --git a/smack-core/src/main/java/org/jivesoftware/smack/AbstractConnectionListener.java b/smack-core/src/main/java/org/jivesoftware/smack/AbstractConnectionListener.java deleted file mode 100644 index f4a6749b9..000000000 --- a/smack-core/src/main/java/org/jivesoftware/smack/AbstractConnectionListener.java +++ /dev/null @@ -1,51 +0,0 @@ -/** - * - * Copyright 2009 the original author or authors - * - * 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; - -/** - * The AbstractConnectionListener class provides an empty implementation for all - * methods defined by the {@link ConnectionListener} interface. This is a - * convenience class which should be used in case you do not need to implement - * all methods. - * - * @author Henning Staib - * @deprecated use {@link ConnectionListener} instead. - */ -// TODO: Remove in Smack 4.5. -@Deprecated -public class AbstractConnectionListener implements ConnectionListener { - @Override - public void connected(XMPPConnection connection) { - // do nothing - } - - @Override - public void authenticated(XMPPConnection connection, boolean resumed) { - // do nothing - } - - @Override - public void connectionClosed() { - // do nothing - } - - @Override - public void connectionClosedOnError(Exception e) { - // do nothing - } - -} 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 ae24f7f2b..8e3e66828 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java @@ -1242,27 +1242,6 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { }); } - @Deprecated - @Override - public void addStanzaInterceptor(StanzaListener packetInterceptor, - StanzaFilter packetFilter) { - if (packetInterceptor == null) { - throw new NullPointerException("Packet interceptor is null."); - } - InterceptorWrapper interceptorWrapper = new InterceptorWrapper(packetInterceptor, packetFilter); - synchronized (interceptors) { - interceptors.put(packetInterceptor, interceptorWrapper); - } - } - - @Deprecated - @Override - public void removeStanzaInterceptor(StanzaListener packetInterceptor) { - synchronized (interceptors) { - interceptors.remove(packetInterceptor); - } - } - private static , MP extends MessageOrPresence> void addInterceptor( Map, GenericInterceptorWrapper> interceptors, Consumer interceptor, Predicate filter) { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java b/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java index 11e931f1a..6df0110f9 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java @@ -1,6 +1,6 @@ /** * - * Copyright 2003-2007 Jive Software, 2017-2022 Florian Schmaus. + * Copyright 2003-2007 Jive Software, 2017-2024 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -857,22 +857,6 @@ public abstract class ConnectionConfiguration { return getThis(); } - /** - * Set the host to connect to by either its fully qualified domain name (FQDN) or its IP. - * - * @param fqdnOrIp a CharSequence either representing the FQDN or the IP of the host. - * @return a reference to this builder. - * @see #setHost(DnsName) - * @see #setHostAddress(InetAddress) - * @since 4.3.2 - * @deprecated use {@link #setHost(CharSequence)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public B setHostAddressByNameOrIp(CharSequence fqdnOrIp) { - return setHost(fqdnOrIp); - } - public B setPort(int port) { if (port < 0 || port > 65535) { throw new IllegalArgumentException( @@ -1021,25 +1005,6 @@ public abstract class ConnectionConfiguration { return getThis(); } - /** - * Sets a custom SSLContext for creating SSL sockets. - *

      - * For more information on how to create a SSLContext see Java Secure Socket Extension (JSEE) Reference Guide: Creating Your Own X509TrustManager - * - * @param context the custom SSLContext for new sockets. - * @return a reference to this builder. - * @deprecated use {@link #setSslContextFactory(SslContextFactory)} instead}. - */ - // TODO: Remove in Smack 4.5. - @Deprecated - public B setCustomSSLContext(SSLContext context) { - return setSslContextFactory(() -> { - return context; - }); - } - /** * Sets a custom SSLContext for creating SSL sockets. *

      @@ -1186,7 +1151,9 @@ public abstract class ConnectionConfiguration { if (!SASLAuthentication.isSaslMechanismRegistered(SASLMechanism.EXTERNAL)) { throw new IllegalArgumentException("SASL " + SASLMechanism.EXTERNAL + " is not registered"); } - setCustomSSLContext(sslContext); + setSslContextFactory(() -> { + return sslContext; + }); throwIfEnabledSaslMechanismsSet(); allowEmptyOrNullUsernames(); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/StanzaListener.java b/smack-core/src/main/java/org/jivesoftware/smack/StanzaListener.java index 52b3168c8..786c5a8b0 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/StanzaListener.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/StanzaListener.java @@ -27,12 +27,6 @@ import org.jivesoftware.smack.packet.Stanza; * the {@link #processStanza(Stanza)} method will be called. This is the * opposite approach to the functionality provided by a {@link StanzaCollector} * which lets you block while waiting for results. - *

      - * Additionally you are able to intercept Packets that are going to be send and - * make modifications to them. You can register a PacketListener as interceptor - * by using {@link XMPPConnection#addStanzaInterceptor(StanzaListener, - * org.jivesoftware.smack.filter.StanzaFilter)} - *

      * * @see XMPPConnection#addAsyncStanzaListener(StanzaListener, org.jivesoftware.smack.filter.StanzaFilter) * @author Matt Tucker 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 cbf05cc6e..c3bd2d414 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java @@ -423,7 +423,6 @@ public interface XMPPConnection { * * @param stanzaListener the stanza listener to notify of new received stanzas. * @param stanzaFilter the stanza filter to use. - * @see #addStanzaInterceptor(StanzaListener, StanzaFilter) * @since 4.1 */ void addSyncStanzaListener(StanzaListener stanzaListener, StanzaFilter stanzaFilter); @@ -449,7 +448,6 @@ public interface XMPPConnection { * * @param stanzaListener the stanza listener to notify of new received stanzas. * @param stanzaFilter the stanza filter to use. - * @see #addStanzaInterceptor(StanzaListener, StanzaFilter) * @since 4.1 */ void addAsyncStanzaListener(StanzaListener stanzaListener, StanzaFilter stanzaFilter); @@ -483,34 +481,6 @@ public interface XMPPConnection { */ void removeStanzaSendingListener(StanzaListener stanzaListener); - /** - * Registers a stanza interceptor with this connection. The interceptor will be - * invoked every time a stanza is about to be sent by this connection. Interceptors - * may modify the stanza to be sent. A stanza filter determines which stanzas - * will be delivered to the interceptor. - * - *

      - * NOTE: For a similar functionality on incoming stanzas, see {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}. - *

      - * - * @param stanzaInterceptor the stanza interceptor to notify of stanzas about to be sent. - * @param stanzaFilter the stanza filter to use. - * @deprecated use {@link #addMessageInterceptor(Consumer, Predicate)} or {@link #addPresenceInterceptor(Consumer, Predicate)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - void addStanzaInterceptor(StanzaListener stanzaInterceptor, StanzaFilter stanzaFilter); - - /** - * Removes a stanza interceptor. - * - * @param stanzaInterceptor the stanza interceptor to remove. - * @deprecated use {@link #removeMessageInterceptor(Consumer)} or {@link #removePresenceInterceptor(Consumer)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - void removeStanzaInterceptor(StanzaListener stanzaInterceptor); - /** * Registers a stanza interceptor with this connection. The interceptor will be * invoked every time a stanza is about to be sent by this connection. Interceptors @@ -611,23 +581,6 @@ public interface XMPPConnection { */ FromMode getFromMode(); - /** - * Get the feature stanza extensions for a given stream feature of the - * server, or null if the server doesn't support that feature. - * - * @param {@link ExtensionElement} type of the feature. - * @param element TODO javadoc me please - * @param namespace TODO javadoc me please - * @return a stanza extensions of the feature or null - * @deprecated use {@link #getFeature(Class)} instead. - */ - // TODO: Remove in Smack 4.5. - @Deprecated - default F getFeature(String element, String namespace) { - QName qname = new QName(namespace, element); - return getFeature(qname); - } - /** * Get the feature stanza extensions for a given stream feature of the * server, or null if the server doesn't support that feature. diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/AbstractTextElement.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/AbstractTextElement.java index 00e82d704..2f475fa06 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/AbstractTextElement.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/AbstractTextElement.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2017-2019 Florian Schmaus + * Copyright © 2017-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,15 +54,4 @@ public abstract class AbstractTextElement implements ExtensionElement { return lang; } - /** - * Deprecated. - * - * @return deprecated - * @deprecated use {@link #getLanguage()} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public final String getLang() { - return lang; - } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java index a38386bfa..8f87dae63 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java @@ -287,20 +287,6 @@ public abstract class IQ extends Stanza implements IqView { return ErrorIQ.createErrorResponse(request, error); } - /** - * Deprecated. - * - * @param request the request. - * @param error the error. - * @return an error IQ. - * @deprecated use {@link #createErrorResponse(IQ, StanzaError)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public static ErrorIQ createErrorResponse(final IQ request, final StanzaError.Builder error) { - return createErrorResponse(request, error.build()); - } - public static ErrorIQ createErrorResponse(final IQ request, final StanzaError.Condition condition) { return createErrorResponse(request, StanzaError.getBuilder(condition).build()); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/Message.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/Message.java index d47cafda7..6063af13b 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/Message.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/Message.java @@ -17,7 +17,6 @@ package org.jivesoftware.smack.packet; -import java.util.List; import java.util.Locale; import javax.xml.namespace.QName; @@ -29,10 +28,6 @@ import org.jivesoftware.smack.util.Objects; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.XmlStringBuilder; -import org.jxmpp.jid.Jid; -import org.jxmpp.jid.impl.JidCreate; -import org.jxmpp.stringprep.XmppStringprepException; - /** * Represents XMPP message packets. A message can be one of several types: * @@ -63,85 +58,7 @@ public final class Message extends MessageOrPresence public static final String ELEMENT = "message"; public static final String BODY = "body"; - private Type type; - - /** - * Creates a new, "normal" message. - * @deprecated use {@link StanzaBuilder}, preferable via {@link StanzaFactory}, instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public Message() { - } - - /** - * Creates a new "normal" message to the specified recipient. - * - * @param to the recipient of the message. - * @deprecated use {@link StanzaBuilder}, preferable via {@link StanzaFactory}, instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public Message(Jid to) { - setTo(to); - } - - /** - * Creates a new message of the specified type to a recipient. - * - * @param to the user to send the message to. - * @param type the message type. - * @deprecated use {@link StanzaBuilder}, preferable via {@link StanzaFactory}, instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public Message(Jid to, Type type) { - this(to); - setType(type); - } - - /** - * Creates a new message to the specified recipient and with the specified body. - * - * @param to the user to send the message to. - * @param body the body of the message. - * @deprecated use {@link StanzaBuilder}, preferable via {@link StanzaFactory}, instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public Message(Jid to, String body) { - this(to); - setBody(body); - } - - /** - * Creates a new message to the specified recipient and with the specified body. - * - * @param to the user to send the message to. - * @param body the body of the message. - * @throws XmppStringprepException if 'to' is not a valid XMPP address. - * @deprecated use {@link StanzaBuilder}, preferable via {@link StanzaFactory}, instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public Message(String to, String body) throws XmppStringprepException { - this(JidCreate.from(to), body); - } - - /** - * Creates a new message with the specified recipient and extension element. - * - * @param to TODO javadoc me please - * @param extensionElement TODO javadoc me please - * @since 4.2 - * @deprecated use {@link StanzaBuilder}, preferable via {@link StanzaFactory}, instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public Message(Jid to, ExtensionElement extensionElement) { - this(to); - addExtension(extensionElement); - } + private final Type type; Message(MessageBuilder messageBuilder) { super(messageBuilder); @@ -170,197 +87,6 @@ public final class Message extends MessageOrPresence return type; } - /** - * Sets the type of the message. - * - * @param type the type of the message. - * @deprecated use {@link StanzaBuilder} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public void setType(Type type) { - this.type = type; - } - - /** - * Sets the subject of the message. The subject is a short description of - * message contents. - * - * @param subject the subject of the message. - * @deprecated use {@link StanzaBuilder} instead. - */ - @Deprecated - // TODO: Remove when stanza builder is ready. - public void setSubject(String subject) { - if (subject == null) { - removeSubject(""); // use empty string because #removeSubject(null) is ambiguous - return; - } - addSubject(null, subject); - } - - /** - * Adds a subject with a corresponding language. - * - * @param language the language of the subject being added. - * @param subject the subject being added to the message. - * @return the new {@link org.jivesoftware.smack.packet.Message.Subject} - * @throws NullPointerException if the subject is null, a null pointer exception is thrown - */ - @Deprecated - // TODO: Remove when stanza builder is ready. - public Subject addSubject(String language, String subject) { - language = Stanza.determineLanguage(this, language); - - List currentSubjects = getExtensions(Subject.class); - for (Subject currentSubject : currentSubjects) { - if (language.equals(currentSubject.getLanguage())) { - throw new IllegalArgumentException("Subject with the language " + language + " already exists"); - } - } - - Subject messageSubject = new Subject(language, subject); - addExtension(messageSubject); - return messageSubject; - } - - /** - * Removes the subject with the given language from the message. - * - * @param language the language of the subject which is to be removed - * @return true if a subject was removed and false if it was not. - */ - @Deprecated - // TODO: Remove when stanza builder is ready. - public boolean removeSubject(String language) { - language = Stanza.determineLanguage(this, language); - for (Subject subject : getExtensions(Subject.class)) { - if (language.equals(subject.language)) { - return removeSubject(subject); - } - } - return false; - } - - /** - * Removes the subject from the message and returns true if the subject was removed. - * - * @param subject the subject being removed from the message. - * @return true if the subject was successfully removed and false if it was not. - */ - @Deprecated - // TODO: Remove when stanza builder is ready. - public boolean removeSubject(Subject subject) { - return removeExtension(subject) != null; - } - - /** - * Sets the body of the message. - * - * @param body the body of the message. - * @see #setBody(String) - * @since 4.2 - * @deprecated use {@link StanzaBuilder} instead. - */ - @Deprecated - // TODO: Remove when stanza builder is ready. - public void setBody(CharSequence body) { - String bodyString; - if (body != null) { - bodyString = body.toString(); - } else { - bodyString = null; - } - setBody(bodyString); - } - - /** - * Sets the body of the message. The body is the main message contents. - * - * @param body the body of the message. - * @deprecated use {@link StanzaBuilder} instead. - */ - @Deprecated - // TODO: Remove when stanza builder is ready. - public void setBody(String body) { - if (body == null) { - removeBody(""); // use empty string because #removeBody(null) is ambiguous - return; - } - addBody(null, body); - } - - /** - * Adds a body with a corresponding language. - * - * @param language the language of the body being added. - * @param body the body being added to the message. - * @return the new {@link org.jivesoftware.smack.packet.Message.Body} - * @throws NullPointerException if the body is null, a null pointer exception is thrown - * @since 3.0.2 - * @deprecated use {@link StanzaBuilder} instead. - */ - @Deprecated - // TODO: Remove when stanza builder is ready. - public Body addBody(String language, String body) { - language = Stanza.determineLanguage(this, language); - - removeBody(language); - - Body messageBody = new Body(language, body); - addExtension(messageBody); - return messageBody; - } - - /** - * Removes the body with the given language from the message. - * - * @param language the language of the body which is to be removed - * @return true if a body was removed and false if it was not. - * @deprecated use {@link StanzaBuilder} instead. - */ - @Deprecated - // TODO: Remove when stanza builder is ready. - public boolean removeBody(String language) { - language = Stanza.determineLanguage(this, language); - for (Body body : getBodies()) { - String bodyLanguage = body.getLanguage(); - if (Objects.equals(bodyLanguage, language)) { - removeExtension(body); - return true; - } - } - return false; - } - - /** - * Removes the body from the message and returns true if the body was removed. - * - * @param body the body being removed from the message. - * @return true if the body was successfully removed and false if it was not. - * @since 3.0.2 - * @deprecated use {@link StanzaBuilder} instead. - */ - @Deprecated - // TODO: Remove when stanza builder is ready. - public boolean removeBody(Body body) { - XmlElement removedElement = removeExtension(body); - return removedElement != null; - } - - /** - * Sets the thread id of the message, which is a unique identifier for a sequence - * of "chat" messages. - * - * @param thread the thread id of the message. - * @deprecated use {@link StanzaBuilder} instead. - */ - @Deprecated - // TODO: Remove when stanza builder is ready. - public void setThread(String thread) { - addExtension(new Message.Thread(thread)); - } - @Override public String getElementName() { return ELEMENT; @@ -412,22 +138,6 @@ public final class Message extends MessageOrPresence return buf; } - /** - * Creates and returns a copy of this message stanza. - *

      - * This does not perform a deep clone, as extension elements are shared between the new and old - * instance. - *

      - * @return a clone of this message. - * @deprecated use {@link #asBuilder()} instead. - */ - // TODO: Remove in Smack 4.5. - @Deprecated - @Override - public Message clone() { - return new Message(this); - } - /** * Represents a message subject, its language and the content of the subject. */ diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageOrPresence.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageOrPresence.java index f48b794a0..c3aa3d180 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageOrPresence.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageOrPresence.java @@ -20,11 +20,6 @@ import org.jivesoftware.smack.XMPPConnection; public abstract class MessageOrPresence> extends Stanza { - @Deprecated - // TODO: Remove in Smack 4.5. - protected MessageOrPresence() { - } - protected MessageOrPresence(StanzaBuilder stanzaBuilder) { super(stanzaBuilder); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/Presence.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/Presence.java index 3490e1a23..caa3942dc 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/Presence.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/Presence.java @@ -1,6 +1,6 @@ /** * - * Copyright 2003-2007 Jive Software, 2020-2021 Florian Schmaus. + * Copyright 2003-2007 Jive Software, 2020-2024 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,12 +21,9 @@ import java.util.List; import java.util.Locale; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.util.Objects; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.XmlStringBuilder; -import org.jxmpp.jid.Jid; - /** * Represents XMPP presence stanzas. Every presence stanza has a type, which is one of * the following values: @@ -78,55 +75,6 @@ public final class Presence extends MessageOrPresence private Mode mode = null; - /** - * Creates a new presence update. Status, priority, and mode are left un-set. - * - * @param type the type. - * @deprecated use {@link PresenceBuilder} or {@link org.jivesoftware.smack.XMPPConnection#getStanzaFactory} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public Presence(Type type) { - // Ensure that the stanza ID is set by calling super(). - super(); - setType(type); - } - - /** - * Creates a new presence with the given type and using the given XMPP address as recipient. - * - * @param to the recipient. - * @param type the type. - * @since 4.2 - * @deprecated use {@link PresenceBuilder} or {@link org.jivesoftware.smack.XMPPConnection#getStanzaFactory} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public Presence(Jid to, Type type) { - this(type); - setTo(to); - } - - /** - * Creates a new presence update with a specified status, priority, and mode. - * - * @param type the type. - * @param status a text message describing the presence update. - * @param priority the priority of this presence update. - * @param mode the mode type for this presence update. - * @deprecated use {@link PresenceBuilder} or {@link org.jivesoftware.smack.XMPPConnection#getStanzaFactory} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public Presence(Type type, String status, int priority, Mode mode) { - // Ensure that the stanza ID is set by calling super(). - super(); - setType(type); - setStatus(status); - setPriority(priority); - setMode(mode); - } - Presence(PresenceBuilder presenceBuilder) { super(presenceBuilder); type = presenceBuilder.type; @@ -186,36 +134,11 @@ public final class Presence extends MessageOrPresence return type; } - /** - * Sets the type of the presence packet. - * - * @param type the type of the presence packet. - * @deprecated use {@link PresenceBuilder} or {@link org.jivesoftware.smack.XMPPConnection#getStanzaFactory} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public void setType(Type type) { - this.type = Objects.requireNonNull(type, "Type cannot be null"); - } - @Override public String getStatus() { return status; } - /** - * Sets the status message of the presence update. The status is free-form text - * describing a user's presence (i.e., "gone to lunch"). - * - * @param status the status message. - * @deprecated use {@link PresenceBuilder} or {@link org.jivesoftware.smack.XMPPConnection#getStanzaFactory} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public void setStatus(String status) { - this.status = status; - } - @Override public int getPriority() { return getPriorityByte(); @@ -233,20 +156,11 @@ public final class Presence extends MessageOrPresence * Sets the priority of the presence. The valid range is -128 through 127. * * @param priority the priority of the presence. - * @throws IllegalArgumentException if the priority is outside the valid range. * @see RFC 6121 § 4.7.2.3. Priority Element * @deprecated use {@link PresenceBuilder} or {@link org.jivesoftware.smack.XMPPConnection#getStanzaFactory} instead. */ @Deprecated - // TODO: Remove in Smack 4.5. - public void setPriority(int priority) { - if (priority < -128 || priority > 127) { - throw new IllegalArgumentException("Priority value " + priority + - " is not valid. Valid range is -128 through 127."); - } - setPriority((byte) priority); - } - + // TODO: Remove in Smack 4.6. public void setPriority(byte priority) { this.priority = priority; } @@ -259,19 +173,6 @@ public final class Presence extends MessageOrPresence return mode; } - /** - * Sets the mode of the presence update. A null presence mode value is interpreted - * to be the same thing as {@link Presence.Mode#available}. - * - * @param mode the mode. - * @deprecated use {@link PresenceBuilder} or {@link org.jivesoftware.smack.XMPPConnection#getStanzaFactory} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public void setMode(Mode mode) { - this.mode = mode; - } - @Override public String getElementName() { return ELEMENT; @@ -346,37 +247,6 @@ public final class Presence extends MessageOrPresence return buf; } - /** - * Creates and returns a copy of this presence stanza. - *

      - * This does not perform a deep clone, as extension elements are shared between the new and old - * instance. - *

      - * @return a clone of this presence. - * @deprecated use {@link #asBuilder()} instead. - */ - // TODO: Remove in Smack 4.5. - @Deprecated - @Override - public Presence clone() { - return new Presence(this); - } - - /** - * Clone this presence and set a newly generated stanza ID as the clone's ID. - * - * @return a "clone" of this presence with a different stanza ID. - * @since 4.1.2 - * @deprecated use {@link #asBuilder(XMPPConnection)} or {@link #asBuilder(String)}instead. - */ - // TODO: Remove in Smack 4.5. - @Deprecated - public Presence cloneWithNewId() { - Presence clone = clone(); - clone.setNewStanzaId(); - return clone; - } - /** * An enum to represent the presence type. Note that presence type is often confused * with presence mode. Generally, if a user is signed in to a server, they have a presence 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 435a344b6..a6d55ca47 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 @@ -159,22 +159,6 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { return id != null; } - /** - * Set the stanza id if none is set. - * - * @return the stanza id. - * @since 4.2 - * @deprecated use {@link StanzaBuilder} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public String setStanzaId() { - if (!hasStanzaIdSet()) { - setNewStanzaId(); - } - return getStanzaId(); - } - /** * Throws an {@link IllegalArgumentException} if this stanza has no stanza ID set. * @@ -255,34 +239,11 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { error = stanzaError; } - /** - * Deprecated. - * @param stanzaError the stanza error. - * @deprecated use {@link StanzaBuilder} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public void setError(StanzaError.Builder stanzaError) { - setError(stanzaError.build()); - } - @Override public final String getLanguage() { return language; } - /** - * Sets the xml:lang of this Stanza. - * - * @param language the xml:lang of this Stanza. - * @deprecated use {@link StanzaBuilder#setLanguage(String)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public void setLanguage(String language) { - this.language = language; - } - @Override public final List getExtensions() { synchronized (extensionElements) { @@ -374,22 +335,6 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { return packetExtension; } - /** - * This method is deprecated. Use preferably {@link #getExtension(Class)} or {@link #getExtensionElement(String, String)}. - * - * @param the type to cast to. - * @param elementName the XML element name of the extension. (May be null) - * @param namespace the XML element namespace of the extension. - * @return the extension, or null if it doesn't exist. - * @deprecated use {@link #getExtension(Class)} or {@link #getExtensionElement(String, String)} instead. - */ - // TODO: Remove in Smack 4.5. - @SuppressWarnings("unchecked") - @Deprecated - public final E getExtension(String elementName, String namespace) { - return (E) getExtensionElement(elementName, namespace); - } - @Override public final XmlElement getExtension(QName qname) { synchronized (extensionElements) { @@ -501,27 +446,6 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { } } - /** - * Removes a stanza extension from the packet. - * - * @param extension the stanza extension to remove. - * @return the removed stanza extension or null. - * @deprecated use {@link StanzaBuilder} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public final XmlElement removeExtension(XmlElement extension) { - QName key = extension.getQName(); - synchronized (extensionElements) { - List list = extensionElements.getAll(key); - boolean removed = list.remove(extension); - if (removed) { - return extension; - } - } - return null; - } - /** * Returns a short String describing the Stanza. This method is suited for log purposes. */ diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/NumberUtil.java b/smack-core/src/main/java/org/jivesoftware/smack/util/NumberUtil.java index 98635309d..836796248 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/NumberUtil.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/NumberUtil.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2015-2020 Florian Schmaus + * Copyright © 2015-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,18 +18,6 @@ package org.jivesoftware.smack.util; public class NumberUtil { - /** - * Checks if the given long is within the range of an unsigned 32-bit integer, the XML type "xs:unsignedInt". - * - * @param value TODO javadoc me please - * @deprecated use {@link #requireUInt32(long)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public static void checkIfInUInt32Range(long value) { - requireUInt32(value); - } - /** * Checks if the given long is within the range of an unsigned 32-bit integer, the XML type "xs:unsignedInt". * diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/ParserUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/ParserUtils.java index 12ce7da7d..7c58f8a12 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/ParserUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/ParserUtils.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2014-2023 Florian Schmaus + * Copyright © 2014-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,8 +23,6 @@ import java.text.ParseException; import java.util.Date; import java.util.Locale; -import javax.xml.namespace.QName; - import org.jivesoftware.smack.datatypes.UInt16; import org.jivesoftware.smack.datatypes.UInt32; import org.jivesoftware.smack.packet.XmlEnvironment; @@ -367,19 +365,6 @@ public class ParserUtils { return parser.getAttributeValue("http://www.w3.org/XML/1998/namespace", "lang"); } - /** - * Get the QName of the current element. - * - * @param parser the parser. - * @return the Qname. - * @deprecated use {@link XmlPullParser#getQName()} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5 - public static QName getQName(XmlPullParser parser) { - return parser.getQName(); - } - public static InternetAddress getInternetAddressIngoringZoneIdAttribute(XmlPullParser parser, String attribute) { String inetAddressString = parser.getAttributeValue(attribute); if (inetAddressString == null) { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java index 041ddde5a..1a66cc0f3 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java @@ -1,6 +1,6 @@ /** * - * Copyright 2003-2007 Jive Software, 2016-2021 Florian Schmaus. + * Copyright 2003-2007 Jive Software, 2016-2024 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,24 +36,6 @@ public class StringUtils { public static final String MD5 = "MD5"; public static final String SHA1 = "SHA-1"; - /** - * Deprecated, do not use. - * - * @deprecated use StandardCharsets.UTF_8 instead. - */ - // TODO: Remove in Smack 4.5. - @Deprecated - public static final String UTF8 = "UTF-8"; - - /** - * Deprecated, do not use. - * - * @deprecated use StandardCharsets.US_ASCII instead. - */ - // TODO: Remove in Smack 4.5. - @Deprecated - public static final String USASCII = "US-ASCII"; - public static final String QUOTE_ENCODE = """; public static final String APOS_ENCODE = "'"; public static final String AMP_ENCODE = "&"; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/TLSUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/TLSUtils.java index c1af8ba61..47469f721 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/TLSUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/TLSUtils.java @@ -1,6 +1,6 @@ /** * - * Copyright 2014-2020 Florian Schmaus + * Copyright 2014-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -68,52 +68,6 @@ public class TLSUtils { return builder; } - /** - * Enable only TLS. Connections created with the given ConnectionConfiguration will only support TLS. - *

      - * According to the Encrypted - * XMPP Manifesto, TLSv1.2 shall be deployed, providing fallback support for SSLv3 and - * TLSv1.1. This method goes one step beyond and upgrades the handshake to use TLSv1 or better. - * This method requires the underlying OS to support all of TLSv1.2 , 1.1 and 1.0. - *

      - * - * @param builder the configuration builder to apply this setting to - * @param Type of the ConnectionConfiguration builder. - * - * @return the given builder - * @deprecated use {@link #setEnabledTlsProtocolsToRecommended(org.jivesoftware.smack.ConnectionConfiguration.Builder)} instead. - */ - // TODO: Remove in Smack 4.5. - @Deprecated - public static > B setTLSOnly(B builder) { - builder.setEnabledSSLProtocols(new String[] { PROTO_TLSV1_2, PROTO_TLSV1_1, PROTO_TLSV1 }); - return builder; - } - - /** - * Enable only TLS and SSLv3. Connections created with the given ConnectionConfiguration will - * only support TLS and SSLv3. - *

      - * According to the Encrypted - * XMPP Manifesto, TLSv1.2 shall be deployed, providing fallback support for SSLv3 and - * TLSv1.1. - *

      - * - * @param builder the configuration builder to apply this setting to - * @param Type of the ConnectionConfiguration builder. - * - * @return the given builder - * @deprecated use {@link #setEnabledTlsProtocolsToRecommended(org.jivesoftware.smack.ConnectionConfiguration.Builder)} instead. - */ - // TODO: Remove in Smack 4.5. - @Deprecated - public static > B setSSLv3AndTLSOnly(B builder) { - builder.setEnabledSSLProtocols(new String[] { PROTO_TLSV1_2, PROTO_TLSV1_1, PROTO_TLSV1, PROTO_SSL3 }); - return builder; - } - /** * Accept all TLS certificates. *

      diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java index 3ecb67877..9eec876c4 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java @@ -1,6 +1,6 @@ /** * - * Copyright 2014-2023 Florian Schmaus + * Copyright 2014-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -138,20 +138,6 @@ public class XmlStringBuilder implements Appendable, CharSequence, Element { return this; } - /** - * Deprecated. - * - * @param element deprecated. - * @return deprecated. - * @deprecated use {@link #append(Element)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public XmlStringBuilder element(Element element) { - assert element != null; - return append(element.toXML()); - } - public XmlStringBuilder optElement(String name, String content) { if (content != null) { element(name, content); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MultiUserChatLight.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MultiUserChatLight.java index 5ebd11197..77262c226 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MultiUserChatLight.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MultiUserChatLight.java @@ -181,21 +181,6 @@ public class MultiUserChatLight { ; } - /** - * Sends a Message to the chat room. - * - * @param message TODO javadoc me please - * the message. - * @throws NotConnectedException if the XMPP connection is not connected. - * @throws InterruptedException if the calling thread was interrupted. - * @deprecated use {@link #sendMessage(MessageBuilder)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public void sendMessage(Message message) throws NotConnectedException, InterruptedException { - sendMessage(message.asBuilder()); - } - /** * Sends a Message to the chat room. * diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/element/OriginIdElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/element/OriginIdElement.java index a50fd99e2..f0766de8b 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/element/OriginIdElement.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/element/OriginIdElement.java @@ -38,28 +38,6 @@ public class OriginIdElement extends StableAndUniqueIdElement { super(id); } - /** - * Add an origin-id element to a message and set the stanzas id to the same id as in the origin-id element. - * - * @param message message. - * @return the added origin-id element. - * @deprecated use {@link #addTo(MessageBuilder)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public static OriginIdElement addOriginId(Message message) { - OriginIdElement originId = message.getExtension(OriginIdElement.class); - if (originId != null) { - return originId; - } - - originId = new OriginIdElement(); - message.addExtension(originId); - // TODO: Find solution to have both the originIds stanzaId and a nice to look at incremental stanzaID. - // message.setStanzaId(originId.getId()); - return originId; - } - /** * Add an origin-id element to a message and set the stanzas id to the same id as in the origin-id element. * diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bob/element/BoBIQ.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bob/element/BoBIQ.java index 085df5fd5..2790e3860 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bob/element/BoBIQ.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bob/element/BoBIQ.java @@ -1,6 +1,6 @@ /** * - * Copyright 2016 Fernando Ramirez, 2020 Florian Schmaus + * Copyright 2016 Fernando Ramirez, 2020-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,18 +65,6 @@ public class BoBIQ extends IQ { this(cid, null); } - /** - * Get the BoB hash. - * - * @return the BoB hash - * @deprecated use {@link #getContentId()} instead. - */ - // TODO: Remove in Smack 4.5. - @Deprecated - public ContentId getBoBHash() { - return cid; - } - /** * Get the BoB hash. * diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java index 520806d0c..3953b9c63 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java @@ -1,6 +1,6 @@ /** * - * Copyright 2003-2007 Jive Software, 2018-2022 Florian Schmaus. + * Copyright 2003-2007 Jive Software, 2018-2024 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -442,27 +442,6 @@ public final class ServiceDiscoveryManager extends Manager { return features.contains(feature); } - /** - * Registers extended discovery information of this XMPP entity. When this - * client is queried for its information this data form will be returned as - * specified by XEP-0128. - *

      - * - * Since no stanza is actually sent to the server it is safe to perform this - * operation before logging to the server. In fact, you may want to - * configure the extended info before logging to the server so that the - * information is already available if it is required upon login. - * - * @param info the data form that contains the extend service discovery - * information. - * @deprecated use {@link #addExtendedInfo(DataForm)} instead. - */ - // TODO: Remove in Smack 4.5 - @Deprecated - public synchronized void setExtendedInfo(DataForm info) { - addExtendedInfo(info); - } - /** * Registers extended discovery information of this XMPP entity. When this * client is queried for its information this data form will be returned as @@ -518,19 +497,6 @@ public final class ServiceDiscoveryManager extends Manager { return CollectionUtil.newListWith(extendedInfos); } - /** - * Returns the data form as List of PacketExtensions, or null if no data form is set. - * This representation is needed by some classes (e.g. EntityCapsManager, NodeInformationProvider) - * - * @return the data form as List of PacketExtensions - * @deprecated use {@link #getExtendedInfo()} instead. - */ - // TODO: Remove in Smack 4.5 - @Deprecated - public List getExtendedInfoAsList() { - return getExtendedInfo(); - } - /** * Removes the data form containing extended service discovery information * from the information returned by this XMPP entity.

      diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java index 23be5dee5..08560bc25 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java @@ -17,7 +17,6 @@ package org.jivesoftware.smackx.disco.packet; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; @@ -83,17 +82,6 @@ public class DiscoverInfo extends IQ implements DiscoverInfoView { } } - /** - * Deprecated. - * - * @deprecated use {@link DiscoverInfoBuilder} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public DiscoverInfo() { - super(ELEMENT, NAMESPACE); - } - /** * Copy constructor. * @@ -114,85 +102,11 @@ public class DiscoverInfo extends IQ implements DiscoverInfoView { identitiesSet.addAll(d.identitiesSet); } - /** - * Adds a new feature to the discovered information. - * - * @param feature the discovered feature - * @return true if the feature did not already exist. - * @deprecated use {@link DiscoverInfoBuilder#addFeature(String)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public boolean addFeature(String feature) { - return addFeature(new Feature(feature)); - } - - /** - * Adds a collection of features to the packet. Does noting if featuresToAdd is null. - * - * @param featuresToAdd TODO javadoc me please - * @deprecated use {@link DiscoverInfoBuilder#addFeatures(Collection)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public void addFeatures(Collection featuresToAdd) { - if (featuresToAdd == null) return; - for (String feature : featuresToAdd) { - addFeature(feature); - } - } - - /** - * Deprecated. - * - * @param feature the future. - * @return true if the feature is new. - * @deprecated use {@link DiscoverInfoBuilder#addFeature(DiscoverInfo.Feature)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public boolean addFeature(Feature feature) { - features.add(feature); - boolean featureIsNew = featuresSet.add(feature); - if (!featureIsNew) { - containsDuplicateFeatures = true; - } - return featureIsNew; - } - @Override public List getFeatures() { return Collections.unmodifiableList(features); } - /** - * Adds a new identity of the requested entity to the discovered information. - * - * @param identity the discovered entity's identity - * @deprecated use {@link DiscoverInfoBuilder#addIdentity(DiscoverInfo.Identity)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public void addIdentity(Identity identity) { - identities.add(identity); - identitiesSet.add(identity.getKey()); - } - - /** - * Adds identities to the DiscoverInfo stanza. - * - * @param identitiesToAdd TODO javadoc me please - * @deprecated use {@link DiscoverInfoBuilder#addIdentities(Collection)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public void addIdentities(Collection identitiesToAdd) { - if (identitiesToAdd == null) return; - for (Identity identity : identitiesToAdd) { - addIdentity(identity); - } - } - @Override public List getIdentities() { return Collections.unmodifiableList(identities); @@ -232,22 +146,6 @@ public class DiscoverInfo extends IQ implements DiscoverInfoView { return node; } - /** - * Sets the node attribute that supplements the 'jid' attribute. A node is merely - * something that is associated with a JID and for which the JID can provide information.

      - * - * Node attributes SHOULD be used only when trying to provide or query information which - * is not directly addressable. - * - * @param node the node attribute that supplements the 'jid' attribute - * @deprecated use {@link DiscoverInfoBuilder#setNode(String)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public void setNode(String node) { - this.node = StringUtils.requireNullOrNotEmpty(node, "The node can not be the empty string"); - } - /** * Returns true if the specified feature is part of the discovered information. * @@ -310,18 +208,6 @@ public class DiscoverInfo extends IQ implements DiscoverInfoView { return new DiscoverInfoBuilder(this, stanzaId); } - /** - * Deprecated, do not use. - * - * @deprecated use {@link #asBuilder(String)} instead. - */ - // TODO: Remove in Smack 4.5. - @Deprecated - @Override - public DiscoverInfo clone() { - return new DiscoverInfo(this); - } - public static DiscoverInfoBuilder builder(XMPPConnection connection) { return new DiscoverInfoBuilder(connection); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/JivePropertiesManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/JivePropertiesManager.java index f02f56c8e..09bf70c5b 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/JivePropertiesManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/JivePropertiesManager.java @@ -1,6 +1,6 @@ /** * - * Copyright 2014 Florian Schmaus. + * Copyright 2014-2024 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,25 +50,6 @@ public class JivePropertiesManager { return javaObjectEnabled; } - /** - * Convenience method to add a property to a packet. - * - * @param packet the stanza to add the property to. - * @param name the name of the property to add. - * @param value the value of the property to add. - * @deprecated use {@link #addProperty(StanzaBuilder, String, Object)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public static void addProperty(Stanza packet, String name, Object value) { - JivePropertiesExtension jpe = (JivePropertiesExtension) packet.getExtension(JivePropertiesExtension.NAMESPACE); - if (jpe == null) { - jpe = new JivePropertiesExtension(); - packet.addExtension(jpe); - } - jpe.setProperty(name, value); - } - /** * Convenience method to add a property to a stanza. * diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultParticipantStatusListener.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultParticipantStatusListener.java deleted file mode 100644 index a496077bc..000000000 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultParticipantStatusListener.java +++ /dev/null @@ -1,98 +0,0 @@ -/** - * - * Copyright 2003-2007 Jive Software. - * - * 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.muc; - -import org.jxmpp.jid.EntityFullJid; -import org.jxmpp.jid.Jid; -import org.jxmpp.jid.parts.Resourcepart; - -/** - * Default implementation of the ParticipantStatusListener interface.

      - * - * This class does not provide any behavior by default. It just avoids having - * to implement all the interface methods if the user is only interested in implementing - * some of the methods. - * - * @author Gaston Dombiak - * @deprecated use {@link ParticipantStatusListener} instead. - */ -// TODO: Remove in Smack 4.5 -@Deprecated -public class DefaultParticipantStatusListener implements ParticipantStatusListener { - - @Override - public void joined(EntityFullJid participant) { - } - - @Override - public void left(EntityFullJid participant) { - } - - @Override - public void kicked(EntityFullJid participant, Jid actor, String reason) { - } - - @Override - public void voiceGranted(EntityFullJid participant) { - } - - @Override - public void voiceRevoked(EntityFullJid participant) { - } - - @Override - public void banned(EntityFullJid participant, Jid actor, String reason) { - } - - @Override - public void membershipGranted(EntityFullJid participant) { - } - - @Override - public void membershipRevoked(EntityFullJid participant) { - } - - @Override - public void moderatorGranted(EntityFullJid participant) { - } - - @Override - public void moderatorRevoked(EntityFullJid participant) { - } - - @Override - public void ownershipGranted(EntityFullJid participant) { - } - - @Override - public void ownershipRevoked(EntityFullJid participant) { - } - - @Override - public void adminGranted(EntityFullJid participant) { - } - - @Override - public void adminRevoked(EntityFullJid participant) { - } - - @Override - public void nicknameChanged(EntityFullJid participant, Resourcepart newNickname) { - } - -} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultUserStatusListener.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultUserStatusListener.java deleted file mode 100644 index 44e396fb0..000000000 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultUserStatusListener.java +++ /dev/null @@ -1,88 +0,0 @@ -/** - * - * Copyright 2003-2007 Jive Software. - * - * 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.muc; - -import org.jxmpp.jid.Jid; - -/** - * Default implementation of the UserStatusListener interface.

      - * - * This class does not provide any behavior by default. It just avoids having - * to implement all the interface methods if the user is only interested in implementing - * some of the methods. - * - * @author Gaston Dombiak - * @deprecated use {@link UserStatusListener} instead. - */ -// TODO: Remove in Smack 4.5. -@Deprecated -public class DefaultUserStatusListener implements UserStatusListener { - - @Override - public void kicked(Jid actor, String reason) { - } - - @Override - public void voiceGranted() { - } - - @Override - public void voiceRevoked() { - } - - @Override - public void banned(Jid actor, String reason) { - } - - @Override - public void membershipGranted() { - } - - @Override - public void membershipRevoked() { - } - - @Override - public void moderatorGranted() { - } - - @Override - public void moderatorRevoked() { - } - - @Override - public void ownershipGranted() { - } - - @Override - public void ownershipRevoked() { - } - - @Override - public void adminGranted() { - } - - @Override - public void adminRevoked() { - } - - @Override - public void roomDestroyed(MultiUserChat alternateMUC, String password, String reason) { - } - -} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucEnterConfiguration.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucEnterConfiguration.java index ef3e17ba7..e2a73dad1 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucEnterConfiguration.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucEnterConfiguration.java @@ -1,6 +1,6 @@ /** * - * Copyright 2015-2020 Florian Schmaus + * Copyright 2015-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60,13 +60,8 @@ public final class MucEnterConfiguration { since = builder.since; timeout = builder.timeout; - final PresenceBuilder joinPresenceBuilder; - if (builder.joinPresence == null) { - joinPresenceBuilder = builder.joinPresenceBuilder.ofType(Presence.Type.available); - } - else { - joinPresenceBuilder = builder.joinPresence.asBuilder(); - } + final PresenceBuilder joinPresenceBuilder = builder.joinPresenceBuilder.ofType(Presence.Type.available); + // Indicate the client supports MUC joinPresenceBuilder.addExtension(new MUCInitialPresence(password, maxChars, maxStanzas, seconds, since)); @@ -95,9 +90,6 @@ public final class MucEnterConfiguration { private final PresenceBuilder joinPresenceBuilder; - // TODO: Remove in Smack 4.5. - private Presence joinPresence; - Builder(Resourcepart nickname, XMPPConnection connection) { this.nickname = Objects.requireNonNull(nickname, "Nickname must not be null"); @@ -107,28 +99,6 @@ public final class MucEnterConfiguration { joinPresenceBuilder = connection.getStanzaFactory().buildPresenceStanza(); } - /** - * Set the presence used to join the MUC room. - *

      - * The 'to' value of the given presence will be overridden and the given presence must be of type - * 'available', otherwise an {@link IllegalArgumentException} will be thrown. - *

      - * - * @param presence TODO javadoc me please - * @return a reference to this builder. - * @deprecated use {@link #withPresence(Consumer)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public Builder withPresence(Presence presence) { - if (presence.getType() != Presence.Type.available) { - throw new IllegalArgumentException("Presence must be of type 'available'"); - } - - joinPresence = presence; - return this; - } - /** * Set the presence used to join the MUC room. *

      diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java index d77b6415a..3c283adc5 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java @@ -718,7 +718,7 @@ public class MultiUserChat { // nickname. if (isJoined()) { try { - leaveSync(); + leave(); } catch (XMPPErrorException | NoResponseException | MucNotJoinedException e) { LOGGER.log(Level.WARNING, "Could not leave MUC prior joining, assuming we are not joined", e); @@ -738,23 +738,6 @@ public class MultiUserChat { return getMyRoomJid() != null; } - /** - * Leave the chat room. - * - * @return the leave presence as reflected by the MUC. - * @throws NotConnectedException if the XMPP connection is not connected. - * @throws InterruptedException if the calling thread was interrupted. - * @throws XMPPErrorException if there was an XMPP error returned. - * @throws NoResponseException if there was no response from the remote entity. - * @throws MucNotJoinedException if not joined to the Multi-User Chat. - * @deprecated use {@link #leave()} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public synchronized Presence leaveSync() throws NotConnectedException, InterruptedException, MucNotJoinedException, NoResponseException, XMPPErrorException { - return leave(); - } - /** * Leave the chat room. * @@ -1028,36 +1011,6 @@ public class MultiUserChat { invite(connection.getStanzaFactory().buildMessageStanza(), user, reason); } - /** - * Invites another user to the room in which one is an occupant using a given Message. The invitation - * will be sent to the room which in turn will forward the invitation to the invitee.

      - * - * If the room is password-protected, the invitee will receive a password to use to join - * the room. If the room is members-only, the invitee may be added to the member list. - * - * @param message the message to use for sending the invitation. - * @param user the user to invite to the room.(e.g. hecate@shakespeare.lit) - * @param reason the reason why the user is being invited. - * @throws NotConnectedException if the XMPP connection is not connected. - * @throws InterruptedException if the calling thread was interrupted. - * @deprecated use {@link #invite(MessageBuilder, EntityBareJid, String)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public void invite(Message message, EntityBareJid user, String reason) throws NotConnectedException, InterruptedException { - // TODO listen for 404 error code when inviter supplies a non-existent JID - message.setTo(room); - - // Create the MUCUser packet that will include the invitation - MUCUser mucUser = new MUCUser(); - MUCUser.Invite invite = new MUCUser.Invite(reason, user); - mucUser.setInvite(invite); - // Add the MUCUser packet that includes the invitation to the message - message.addExtension(mucUser); - - connection.sendStanza(message); - } - /** * Invites another user to the room in which one is an occupant using a given Message. The invitation * will be sent to the room which in turn will forward the invitation to the invitee.

      @@ -2137,20 +2090,6 @@ public class MultiUserChat { ; } - /** - * Sends a Message to the chat room. - * - * @param message the message. - * @throws NotConnectedException if the XMPP connection is not connected. - * @throws InterruptedException if the calling thread was interrupted. - * @deprecated use {@link #sendMessage(MessageBuilder)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public void sendMessage(Message message) throws NotConnectedException, InterruptedException { - sendMessage(message.asBuilder()); - } - /** * Sends a Message to the chat room. * diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatException.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatException.java index 1f7f930a2..11de8dff4 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatException.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatException.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2014-2015 Florian Schmaus + * Copyright © 2014-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -88,7 +88,7 @@ public abstract class MultiUserChatException extends SmackException { /** * Thrown when trying to enter a MUC room that is not hosted a domain providing a MUC service. - * Try {@link MultiUserChatManager#getXMPPServiceDomains()} for a list of client-local domains + * Try {@link MultiUserChatManager#getMucServiceDomains()} for a list of client-local domains * providing a MUC service. */ public static class NotAMucServiceException extends MultiUserChatException { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java index e8012406f..7ebfdfdc9 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2014-2021 Florian Schmaus + * Copyright © 2014-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -421,22 +421,6 @@ public final class MultiUserChatManager extends Manager { return serviceDiscoveryManager.findServices(MUCInitialPresence.NAMESPACE, false, false); } - /** - * Returns a collection with the XMPP addresses of the Multi-User Chat services. - * - * @return a collection with the XMPP addresses of the Multi-User Chat services. - * @throws XMPPErrorException if there was an XMPP error returned. - * @throws NoResponseException if there was no response from the remote entity. - * @throws NotConnectedException if the XMPP connection is not connected. - * @throws InterruptedException if the calling thread was interrupted. - * @deprecated use {@link #getMucServiceDomains()} instead. - */ - // TODO: Remove in Smack 4.5 - @Deprecated - public List getXMPPServiceDomains() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - return getMucServiceDomains(); - } - /** * Check if the provided domain bare JID provides a MUC service. * diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/PepManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/PepManager.java index 7eaad0db4..7aa6b2d0c 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/PepManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/PepManager.java @@ -1,6 +1,6 @@ /** * - * Copyright 2003-2007 Jive Software, 2015-2020 Florian Schmaus + * Copyright 2003-2007 Jive Software, 2015-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -248,32 +248,6 @@ public final class PepManager extends Manager { return pepPubSubManager; } - /** - * Adds a listener to PEPs. The listener will be fired anytime PEP events are received from remote XMPP clients. - * - * @param pepListener a roster exchange listener. - * @return true if pepListener was added. - * @deprecated use {@link #addPepEventListener(String, Class, PepEventListener)} instead. - */ - // TODO: Remove in Smack 4.5 - @Deprecated - public boolean addPepListener(PepListener pepListener) { - return pepListeners.add(pepListener); - } - - /** - * Removes a listener from PEP events. - * - * @param pepListener a roster exchange listener. - * @return true, if pepListener was removed. - * @deprecated use {@link #removePepEventListener(PepEventListener)} instead. - */ - // TODO: Remove in Smack 4.5. - @Deprecated - public boolean removePepListener(PepListener pepListener) { - return pepListeners.remove(pepListener); - } - /** * Publish an event. * diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/ItemDeleteEvent.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/ItemDeleteEvent.java index 424c3da0b..3ac132246 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/ItemDeleteEvent.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/ItemDeleteEvent.java @@ -31,7 +31,7 @@ public class ItemDeleteEvent extends SubscriptionEvent { * Constructs an ItemDeleteEvent that indicates the supplied * items (by id) have been deleted, and that the event matches the listed * subscriptions. The subscriptions would have been created by calling - * {@link LeafNode#subscribe(String)}. + * {@link LeafNode#subscribe(org.jxmpp.Jid)}. * * @param nodeId The id of the node the event came from * @param deletedItemIds The item ids of the items that were deleted. diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java index 4db909dfa..9741ce51f 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java @@ -52,8 +52,6 @@ import org.jivesoftware.smackx.shim.packet.HeadersExtension; import org.jivesoftware.smackx.xdata.packet.DataForm; import org.jxmpp.jid.Jid; -import org.jxmpp.jid.impl.JidCreate; -import org.jxmpp.stringprep.XmppStringprepException; public abstract class Node { protected final PubSubManager pubSubManager; @@ -403,39 +401,6 @@ public abstract class Node { return reply.getExtension(PubSubElementType.SUBSCRIPTION); } - /** - * The user subscribes to the node using the supplied jid. The - * bare jid portion of this one must match the jid for the connection. - * - * Please note that the {@link Subscription.State} should be checked - * on return since more actions may be required by the caller. - * {@link Subscription.State#pending} - The owner must approve the subscription - * request before messages will be received. - * {@link Subscription.State#unconfigured} - If the {@link Subscription#isConfigRequired()} is true, - * the caller must configure the subscription before messages will be received. If it is false - * the caller can configure it but is not required to do so. - * - * @param jidString The jid to subscribe as. - * @return The subscription - * @throws XMPPErrorException if there was an XMPP error returned. - * @throws NoResponseException if there was no response from the remote entity. - * @throws NotConnectedException if the XMPP connection is not connected. - * @throws InterruptedException if the calling thread was interrupted. - * @throws IllegalArgumentException if the provided string is not a valid JID. - * @deprecated use {@link #subscribe(Jid)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public Subscription subscribe(String jidString) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - Jid jid; - try { - jid = JidCreate.from(jidString); - } catch (XmppStringprepException e) { - throw new IllegalArgumentException(e); - } - return subscribe(jid); - } - /** * The user subscribes to the node using the supplied jid and subscription * options. The bare jid portion of this one must match the jid for the @@ -466,42 +431,6 @@ public abstract class Node { return reply.getExtension(PubSubElementType.SUBSCRIPTION); } - /** - * The user subscribes to the node using the supplied jid and subscription - * options. The bare jid portion of this one must match the jid for the - * connection. - * - * Please note that the {@link Subscription.State} should be checked - * on return since more actions may be required by the caller. - * {@link Subscription.State#pending} - The owner must approve the subscription - * request before messages will be received. - * {@link Subscription.State#unconfigured} - If the {@link Subscription#isConfigRequired()} is true, - * the caller must configure the subscription before messages will be received. If it is false - * the caller can configure it but is not required to do so. - * - * @param jidString The jid to subscribe as. - * @param subForm TODO javadoc me please - * - * @return The subscription - * @throws XMPPErrorException if there was an XMPP error returned. - * @throws NoResponseException if there was no response from the remote entity. - * @throws NotConnectedException if the XMPP connection is not connected. - * @throws InterruptedException if the calling thread was interrupted. - * @throws IllegalArgumentException if the provided string is not a valid JID. - * @deprecated use {@link #subscribe(Jid, FillableSubscribeForm)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public Subscription subscribe(String jidString, FillableSubscribeForm subForm) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - Jid jid; - try { - jid = JidCreate.from(jidString); - } catch (XmppStringprepException e) { - throw new IllegalArgumentException(e); - } - return subscribe(jid, subForm); - } - /** * Remove the subscription related to the specified JID. This will only * work if there is only 1 subscription. If there are multiple subscriptions, diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java index 6744c5713..3c7c756de 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java @@ -156,33 +156,6 @@ public final class PubSubManager extends Manager { return pubSubManager; } - /** - * Deprecated. - * - * @param connection the connection. - * @return the PubSub manager for the given connection. - * @deprecated use {@link #getInstanceFor(XMPPConnection)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public static PubSubManager getInstance(XMPPConnection connection) { - return getInstanceFor(connection); - } - - /** - * Deprecated. - * - * @param connection the connection. - * @param pubSubService the XMPP address of the PubSub service. - * @return the PubSub manager for the given connection. - * @deprecated use {@link #getInstanceFor(XMPPConnection, BareJid)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5. - public static PubSubManager getInstance(XMPPConnection connection, BareJid pubSubService) { - return getInstanceFor(connection, pubSubService); - } - /** * Create a pubsub manager associated to the specified connection where * the pubsub requests require a specific to address for packets. diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/SimplePayload.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/SimplePayload.java index 730c4c4c8..95667a6e5 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/SimplePayload.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/SimplePayload.java @@ -59,27 +59,6 @@ public class SimplePayload implements XmlElement { ns = StringUtils.requireNotNullNorEmpty(qname.getNamespaceURI(), "Could not determine namespace from XML payload"); } - /** - * Construct a SimplePayload object with the specified element name, - * namespace and content. The content must be well formed XML. - * - * @param elementName The root element name (of the payload) - * @param namespace The namespace of the payload, null if there is none - * @param xmlPayload The payload data - * @deprecated use {@link #SimplePayload(String)} instead. - */ - // TODO: Remove in Smack 4.5 - @Deprecated - public SimplePayload(String elementName, String namespace, CharSequence xmlPayload) { - this(xmlPayload.toString()); - if (!elementName.equals(this.elemName)) { - throw new IllegalArgumentException(); - } - if (!namespace.equals(this.ns)) { - throw new IllegalArgumentException(); - } - } - @Override public String getElementName() { return elemName; 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 0bfbba9b2..5aefdeeff 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 @@ -106,7 +106,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(); + // vcard.setStanzaId(); TODO FIXME connection().sendIqRequestAndWaitForResponse(vcard); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/FormField.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/FormField.java index a2ad8cb76..7465f6d2d 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/FormField.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/FormField.java @@ -1,6 +1,6 @@ /** * - * Copyright 2003-2007 Jive Software, 2019-2021 Florian Schmaus. + * Copyright 2003-2007 Jive Software, 2019-2024 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -342,23 +342,6 @@ public abstract class FormField implements XmlElement { return XmppDateTime.parseXEP0082Date(valueString); } - /** - * Returns the field's name, also known as the variable name in case this is an filled out answer form. - *

      - * According to XEP-4 § 3.2 the variable name (the 'var' attribute) - * "uniquely identifies the field in the context of the form" (if the field is not of type 'fixed', in which case - * the field "MAY possess a 'var' attribute") - *

      - * - * @return the field's name. - * @deprecated use {@link #getFieldName()} instead. - */ - // TODO: Remove in Smack 4.5 - @Deprecated - public String getVariable() { - return getFieldName(); - } - /** * Returns the field's name, also known as the variable name in case this is an filled out answer form. *

      diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/packet/DataForm.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/packet/DataForm.java index 9ab354d57..e9f2da625 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/packet/DataForm.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/packet/DataForm.java @@ -1,6 +1,6 @@ /** * - * Copyright 2003-2007 Jive Software, 2020-2021 Florian Schmaus. + * Copyright 2003-2007 Jive Software, 2020-2024 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,7 +33,6 @@ import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.packet.StanzaView; import org.jivesoftware.smack.packet.XmlEnvironment; import org.jivesoftware.smack.util.CollectionUtil; -import org.jivesoftware.smack.util.Objects; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.XmlStringBuilder; @@ -356,8 +355,7 @@ public final class DataForm implements ExtensionElement { } public static final class Builder { - // TODO: Make this field final once setType() is gone. - private Type type; + private final Type type; private String title; private List instructions; private ReportedData reportedData; @@ -409,20 +407,6 @@ public final class DataForm implements ExtensionElement { } } - /** - * Deprecated do not use. - * - * @param type the type. - * @return a reference to this builder. - * @deprecated use {@link DataForm#builder(Type)} instead. - */ - @Deprecated - // TODO: Remove in Smack 4.5 and then make this.type final. - public Builder setType(Type type) { - this.type = Objects.requireNonNull(type); - return this; - } - /** * Sets the description of the data. It is similar to the title on a web page or an X window. * You can put a <title/> on either a form to fill out, or a set of data results. diff --git a/smack-im/src/main/java/org/jivesoftware/smack/chat/Chat.java b/smack-im/src/main/java/org/jivesoftware/smack/chat/Chat.java index a00871964..a9cbe98b1 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/chat/Chat.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/chat/Chat.java @@ -133,10 +133,12 @@ public class Chat { public void sendMessage(Message message) throws NotConnectedException, InterruptedException { // Force the recipient, message type, and thread ID since the user elected // to send the message through this chat object. - message.setTo(participant); - message.setType(Message.Type.chat); - message.setThread(threadID); - chatManager.sendMessage(this, message); + Message chatMessage = message.asBuilder() + .to(participant) + .ofType(Message.Type.chat) + .setThread(threadID) + .build(); + chatManager.sendMessage(this, chatMessage); } /** @@ -199,10 +201,10 @@ public class Chat { // Because the collector and listeners are expecting a thread ID with // a specific value, set the thread ID on the message even though it // probably never had one. - message.setThread(threadID); + Message chatMessage = message.asBuilder().setThread(threadID).build(); for (ChatMessageListener listener : listeners) { - listener.processMessage(this, message); + listener.processMessage(this, chatMessage); } } diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java index 4b38ef567..b51542015 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java @@ -1,6 +1,6 @@ /** * - * Copyright 2003-2007 Jive Software, 2016-2022 Florian Schmaus. + * Copyright 2003-2007 Jive Software, 2016-2024 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -218,7 +218,7 @@ public final class Roster extends Manager { *

      * This method will never return null, instead if the user has not yet logged into * the server all modifying methods of the returned roster object - * like {@link Roster#createEntry(BareJid, String, String[])}, + * like {@link Roster#createItemAndRequestSubscription(BareJid, String, String[])}, * {@link Roster#removeEntry(RosterEntry)} , etc. except adding or removing * {@link RosterListener}s will throw an IllegalStateException. *

      @@ -754,27 +754,6 @@ public final class Roster extends Manager { return group; } - /** - * Creates a new roster entry and presence subscription. The server will asynchronously - * update the roster with the subscription status. - * - * @param user the user. (e.g. johndoe@jabber.org) - * @param name the nickname of the user. - * @param groups the list of group names the entry will belong to, or null if - * the roster entry won't belong to a group. - * @throws NoResponseException if there was no response from the server. - * @throws XMPPErrorException if an XMPP exception occurs. - * @throws NotLoggedInException If not logged in. - * @throws NotConnectedException if the XMPP connection is not connected. - * @throws InterruptedException if the calling thread was interrupted. - * @deprecated use {@link #createItemAndRequestSubscription(BareJid, String, String[])} instead. - */ - // TODO: Remove in Smack 4.5. - @Deprecated - public void createEntry(BareJid user, String name, String[] groups) throws NotLoggedInException, NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - createItemAndRequestSubscription(user, name, groups); - } - /** * Creates a new roster item. The server will asynchronously update the roster with the subscription status. *

      From 822115e9f6b41f57d478a192964039d9e99eada2 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 14 Sep 2024 21:35:33 +0200 Subject: [PATCH 123/150] Smack 4.5.0-beta1 --- version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version b/version index 196915bff..bd1d3bd13 100644 --- a/version +++ b/version @@ -1 +1 @@ -4.5.0-alpha4-SNAPSHOT +4.5.0-beta1 From b1071412e280071136c70c4ea8b190b29ee48d4a Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 14 Sep 2024 21:46:55 +0200 Subject: [PATCH 124/150] Smack 4.5.0-beta2-SNAPSHOT --- version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version b/version index bd1d3bd13..b0a50c884 100644 --- a/version +++ b/version @@ -1 +1 @@ -4.5.0-beta1 +4.5.0-beta2-SNAPSHOT From 94375e32084bfbaa8d75e0f876c9d1b23dbdd59f Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 15 Sep 2024 19:09:19 +0200 Subject: [PATCH 125/150] Bump minimum Android SDK version to 21 Fixes SMACK-951 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index c8dbd828e..9685a6b2f 100644 --- a/build.gradle +++ b/build.gradle @@ -142,7 +142,7 @@ allprojects { // - https://issues.igniterealtime.org/browse/SMACK-858 jxmppVersion = '[1.0.0, 1.0.999]' miniDnsVersion = '[1.0.0, 1.0.999]' - smackMinAndroidSdk = 19 + smackMinAndroidSdk = 21 junitVersion = '5.7.1' commonsIoVersion = '2.6' bouncyCastleVersion = '1.73' @@ -578,7 +578,7 @@ configure (project(':smack-java8-full')) { configure (androidProjects + androidBootClasspathProjects) { apply plugin: 'ru.vyarus.animalsniffer' dependencies { - signature "net.sf.androidscents.signature:android-api-level-${smackMinAndroidSdk}:4.4.2_r4@signature" + signature "net.sf.androidscents.signature:android-api-level-${smackMinAndroidSdk}:5.0.1_r2@signature" } animalsniffer { sourceSets = [sourceSets.main] From 49379afd3f5801bb85c4c97027d4af5e968cc237 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 15 Sep 2024 19:09:45 +0200 Subject: [PATCH 126/150] [core] Correctly handle BCP 42 language tag creation from Locale for xml:lang Fixes SMACK-952 --- .../smack/ConnectionConfiguration.java | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java b/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java index 6df0110f9..76b5a8e39 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java @@ -544,19 +544,21 @@ public abstract class ConnectionConfiguration { * Returns the xml:lang string of the stream language to use when connecting to the server. * *

      If the developer sets the language to null, this will also return null, leading to - * the removal of the xml:lang tag from the stream. If a Locale("") is configured, this will - * return "", which can be used as an override.

      + * the removal of the xml:lang tag from the stream.

      * - * @return the stream language to use when connecting to the server. + * @return the stream language to use when connecting to the server or null. */ public String getXmlLang() { - // TODO: Change to Locale.toLanguageTag() once Smack's minimum Android API level is 21 or higher. - // This will need a workaround for new Locale("").getLanguageTag() returning "und". Expected - // behavior of this function: - // - returns null if language is null - // - returns "" if language.getLanguage() returns the empty string - // - returns language.toLanguageTag() otherwise - return language != null ? language.toString().replace("_", "-") : null; + if (language == null) { + return null; + } + + String languageTag = language.toLanguageTag(); + if (languageTag.equals("und")) { + return null; + } + + return languageTag; } /** From 1c1f57d9ffa92ae8db3c4aebb5c5f9d5b0cd4f8f Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 15 Sep 2024 19:10:14 +0200 Subject: [PATCH 127/150] [core] Refine javadoc for ConnectionConfiguration.getLanguage() --- .../java/org/jivesoftware/smack/ConnectionConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java b/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java index 76b5a8e39..098f4b6a1 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java @@ -534,7 +534,7 @@ public abstract class ConnectionConfiguration { /** * Returns the stream language to use when connecting to the server. * - * @return the stream language to use when connecting to the server. + * @return the stream language to use when connecting to the server or null. */ public Locale getLanguage() { return language; From 8d7952cec354964497c31576fcc1e90fcf211d12 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 15 Sep 2024 19:44:46 +0200 Subject: [PATCH 128/150] Bump MiniDNS version to 1.1.0-alpha3 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 9685a6b2f..7d1ca3285 100644 --- a/build.gradle +++ b/build.gradle @@ -141,7 +141,7 @@ allprojects { // - https://issues.apache.org/jira/browse/MNG-6232 // - https://issues.igniterealtime.org/browse/SMACK-858 jxmppVersion = '[1.0.0, 1.0.999]' - miniDnsVersion = '[1.0.0, 1.0.999]' + miniDnsVersion = '[1.1.0-alpha3, 1.1.999]' smackMinAndroidSdk = 21 junitVersion = '5.7.1' commonsIoVersion = '2.6' From ab16e1a32cb0230c76aa5efb14dc2b2bc4d4db97 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 15 Sep 2024 19:45:15 +0200 Subject: [PATCH 129/150] Bump jxmpp version to 1.1.0-beta1 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 7d1ca3285..8570669b9 100644 --- a/build.gradle +++ b/build.gradle @@ -140,7 +140,7 @@ allprojects { // See also: // - https://issues.apache.org/jira/browse/MNG-6232 // - https://issues.igniterealtime.org/browse/SMACK-858 - jxmppVersion = '[1.0.0, 1.0.999]' + jxmppVersion = '[1.1.0-beta1, 1.1.999]' miniDnsVersion = '[1.1.0-alpha3, 1.1.999]' smackMinAndroidSdk = 21 junitVersion = '5.7.1' From fd1f69203141f5c4b22cdf87708c7aa94672143d Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 15 Sep 2024 19:50:40 +0200 Subject: [PATCH 130/150] Smack 4.5.0-beta2 --- version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version b/version index b0a50c884..54e94febc 100644 --- a/version +++ b/version @@ -1 +1 @@ -4.5.0-beta2-SNAPSHOT +4.5.0-beta2 From 5a822a6631cdef5813eabf31d7a27493438a5159 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 15 Sep 2024 20:00:57 +0200 Subject: [PATCH 131/150] Smack 4.5.0-beta3-SNAPSHOT --- version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version b/version index 54e94febc..5514d567b 100644 --- a/version +++ b/version @@ -1 +1 @@ -4.5.0-beta2 +4.5.0-beta3-SNAPSHOT From d8d066b831dd0f7005f62d5156e6de55d0e8021b Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 16 Sep 2024 08:59:04 +0200 Subject: [PATCH 132/150] [github ci] Install Android SDK 21 --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 36bc92de9..20c87d49e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,10 +52,10 @@ jobs: - name: Install GraphViz run: sudo apt update && sudo apt install graphviz - name: Install Android SDK Manager - uses: android-actions/setup-android@v2 + uses: android-actions/setup-android@v3 - name: Install Android SDK run: | - sdkmanager "platforms;android-19" + sdkmanager "platforms;android-21" # Testing - name: Gradle Check From e4fcdb68795fe3d311a78cc44824b9e92c0c64ad Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Wed, 18 Sep 2024 12:18:38 +0200 Subject: [PATCH 133/150] [sint] Fix compatibility with Smack 4.5.0-beta2 Due to a change in Smack 4.5.0-beta2, test execution of (all) SINT tests is aborted when `FormTest` is executed. It appears that Smack now has more strict argument validation when setting thread IDs on message stanzas. This validation should not fail for the tests that are shipped with Smack. This is the stack trace when executing the failing test (which no longer occurs after the change in this commit is applied): ``` Exception in thread "main" java.lang.IllegalArgumentException: thread must not be null nor empty at org.jivesoftware.smack.util.StringUtils.requireNotNullNorEmpty(StringUtils.java:533) at org.jivesoftware.smack.packet.Message$Thread.(Message.java:326) at org.jivesoftware.smack.packet.MessageBuilder.setThread(MessageBuilder.java:70) at org.jivesoftware.smack.packet.MessageBuilder.setThread(MessageBuilder.java:66) at org.jivesoftware.smackx.xdata.FormTest.testFilloutForm(FormTest.java:133) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework.lambda$runTests$0(SmackIntegrationTestFramework.java:476) at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework.runConcreteTest(SmackIntegrationTestFramework.java:556) at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework$PreparedTest.run(SmackIntegrationTestFramework.java:764) at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework.runTests(SmackIntegrationTestFramework.java:544) at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework.run(SmackIntegrationTestFramework.java:277) at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework.main(SmackIntegrationTestFramework.java:115) ``` --- .../java/org/jivesoftware/smackx/xdata/FormTest.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/xdata/FormTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/xdata/FormTest.java index 667beedb7..9e127b85e 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/xdata/FormTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/xdata/FormTest.java @@ -128,22 +128,22 @@ public class FormTest extends AbstractSmackIntegrationTest { completedForm.setAnswer("time", true); completedForm.setAnswer("age", 20); // Create a new message to send with the completed form - msg2 = StanzaBuilder.buildMessage() + Message msg3 = StanzaBuilder.buildMessage() .to(conOne.getUser().asBareJid()) - .setThread(msg.getThread()) + .setThread(msg2.getThread()) .ofType(Message.Type.chat) .setBody("To enter a case please fill out this form and send it back to me") // Add the completed form to the message .addExtension(completedForm.getDataFormToSubmit()) .build(); // Send the message with the completed form - conTwo.sendStanza(msg2); + conTwo.sendStanza(msg3); // Get the message with the completed form - Message msg3 = collector.nextResult(); - assertNotNull(msg3, "Message not found"); + Message msg4 = collector.nextResult(); + assertNotNull(msg4, "Message not found"); // Retrieve the completed form - final DataForm completedForm2 = DataForm.from(msg3); + final DataForm completedForm2 = DataForm.from(msg4); assertNotNull(completedForm2); assertNotNull(completedForm2.getField("name")); assertNotNull(completedForm2.getField("description")); From 1e5d34eacf9a84f6dc2b5e918274d587bd35c030 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 25 Sep 2024 11:43:47 +0200 Subject: [PATCH 134/150] Bump to Gradle 8.10.2, require Java 11 Bump Gradle from 6.8.3 to 8.10.2 and increase the minimum required Java version from 8 to 11 (SMACK-953). The switch from Java 8 to 11 caused some Bytecode portability issues regarding NIO Buffers. Java changed with version 9 the return type of some subclasses of Buffer to return the specific Buffer type instead of the Buffer superclass [JDK-4774077]. For example, ByteBuffer.filp() previously returned Buffer, while it does return ByteBuffer now. This sensible change was not reflected by the Android API [1], which means that AnimalSniffer rightfully started to complain that there is no method "ByteBuffer ByteBuffer.flip()" in Android, there is only "Buffer ByteBuffer.flip()", and those are incompatible methods on Java's Bytecode layer. As workaround, this changes return charBuffer.flip().toString(); to ((java.nio.Buffer) charBuffer).flip(); return charBuffer.toString(); to restore the Bytecode portability between Android and Java. Errorprone also got new checks, of which JavaUtilDate and JdkObsolete are wroth mentioning. JavaUtilData basically strongly recommends to use Java's newer time API over java.util.Date. But since Smack was Java 8 until now, j.u.Date is widely used. Similar JdkObsolete mentions obsolete JDK APIs, like data structures like Vector and Stack. But mostly LinkedList, which should usually be replaced by ArrayList. And this is what this commit largely does. JDK-4774077: https://bugs.openjdk.org/browse/JDK-4774077 1: https://issuetracker.google.com/issues/369219141 --- .github/workflows/ci.yml | 32 +- Makefile | 30 + build-logic/build.gradle | 16 + build-logic/settings.gradle | 1 + ....android-boot-classpath-conventions.gradle | 6 + ...erealtime.smack.android-conventions.gradle | 10 + ...ltime.smack.application-conventions.gradle | 12 + ...terealtime.smack.global-conventions.gradle | 37 + ...ltime.smack.java-common-conventions.gradle | 373 ++++++++++ ...erealtime.smack.javadoc-conventions.gradle | 30 + build.gradle | 690 +----------------- gradle/wrapper/gradle-wrapper.jar | Bin 59203 -> 43583 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- gradlew | 297 +++++--- gradlew.bat | 37 +- repl | 11 +- resources/releasedocs/README.html | 221 ------ settings.gradle | 4 + smack-android-extensions/build.gradle | 8 +- smack-android/build.gradle | 20 +- smack-bosh/build.gradle | 5 + smack-core/build.gradle | 13 +- .../smack/AbstractXMPPConnection.java | 15 +- .../jivesoftware/smack/ScheduledAction.java | 4 +- .../org/jivesoftware/smack/SmackReactor.java | 3 +- .../jivesoftware/smack/StanzaCollector.java | 12 +- .../jivesoftware/smack/XMPPConnection.java | 2 + .../ModularXmppClientToServerConnection.java | 2 +- .../zlib/ZlibXmppCompressionFactory.java | 16 +- .../smack/debugger/ConsoleDebugger.java | 1 + .../smack/initializer/UrlInitializer.java | 6 +- .../smack/packet/AbstractError.java | 3 +- .../jivesoftware/smack/packet/Mechanisms.java | 6 +- .../packet/StandardExtensionElement.java | 4 +- .../jivesoftware/smack/packet/StanzaView.java | 6 +- .../smack/provider/ProviderFileLoader.java | 10 +- .../smack/provider/ProviderManager.java | 4 +- .../smack/sasl/core/ScramMechanism.java | 1 + .../org/jivesoftware/smack/util/MultiMap.java | 5 +- .../smack/util/PacketParserUtils.java | 7 +- .../jivesoftware/smack/util/PacketUtil.java | 4 +- .../org/jivesoftware/smack/util/Pair.java | 3 +- .../jivesoftware/smack/util/StringUtils.java | 5 +- .../smack/util/XmppElementUtil.java | 1 + .../jivesoftware/smack/DummyConnection.java | 4 +- smack-debug-slf4j/build.gradle | 4 + smack-debug/build.gradle | 4 + .../smackx/debugger/EnhancedDebugger.java | 3 + .../debugger/EnhancedDebuggerWindow.java | 2 +- smack-examples/build.gradle | 4 + .../smack/examples/XmppTools.java | 3 +- smack-experimental/build.gradle | 5 + .../iot/data/element/IoTFieldsExtension.java | 1 + .../element/JingleFileTransferChild.java | 3 +- .../jivesoftware/smackx/mam/MamManager.java | 4 +- .../spoiler/element/SpoilerElement.java | 1 + .../element/TimestampAffixElement.java | 1 + .../jivesoftware/smackx/mam/FiltersTest.java | 4 +- smack-extensions/build.gradle | 5 + .../ibb/InBandBytestreamManager.java | 6 +- .../socks5/Socks5BytestreamManager.java | 5 +- .../bytestreams/socks5/Socks5Proxy.java | 6 +- .../smackx/caps/EntityCapsManager.java | 6 +- .../smackx/disco/ServiceDiscoveryManager.java | 3 +- .../smackx/disco/packet/DiscoverInfo.java | 3 +- .../smackx/disco/packet/DiscoverItems.java | 4 +- .../provider/RegistrationProvider.java | 4 +- .../smackx/iqversion/packet/Version.java | 4 +- .../last_interaction/element/IdleElement.java | 1 + .../smackx/muc/MucEnterConfiguration.java | 2 - .../smackx/muc/MultiUserChat.java | 4 +- .../smackx/muc/MultiUserChatManager.java | 1 + .../smackx/pubsub/ItemPublishEvent.java | 1 + .../smackx/pubsub/packet/PubSub.java | 2 +- .../jivesoftware/smackx/rsm/RSMManager.java | 8 +- .../si/provider/StreamInitiationProvider.java | 1 + .../smackx/caps/EntityCapsManagerTest.java | 6 +- .../java/org/jivesoftware/util/Protocol.java | 1 + smack-im/build.gradle | 8 + .../jivesoftware/smack/roster/RosterUtil.java | 4 +- smack-integration-test/build.gradle | 16 +- .../smack/inttest/Configuration.java | 6 +- .../SmackIntegrationTestFramework.java | 9 +- .../java/org/jivesoftware/smack/ChatTest.java | 2 +- smack-java8-full/build.gradle | 5 + smack-java8/build.gradle | 8 +- .../smack/java7/XmppHostnameVerifier.java | 8 +- smack-jingle-old/build.gradle | 4 + .../sshare/api/OctTreeQuantizer.java | 1 + smack-legacy/build.gradle | 5 + .../smackx/workgroup/agent/AgentRoster.java | 2 +- .../smackx/workgroup/agent/AgentSession.java | 2 + .../ext/history/AgentChatHistory.java | 2 + .../smackx/workgroup/packet/QueueDetails.java | 1 + .../smackx/workgroup/util/MetaDataUtils.java | 5 +- .../build.gradle | 15 +- smack-omemo-signal/build.gradle | 8 + smack-omemo/build.gradle | 8 + .../smackx/omemo/FileBasedOmemoStore.java | 7 + .../smackx/omemo/OmemoService.java | 3 + .../jivesoftware/smackx/omemo/OmemoStore.java | 2 + .../smackx/omemo/OmemoServiceTest.java | 1 + .../smackx/omemo/OmemoStoreTest.java | 4 +- smack-openpgp/build.gradle | 8 + .../smackx/ox/OpenPgpContact.java | 1 + .../smackx/ox/OpenPgpManager.java | 1 + .../jivesoftware/smackx/ox/OpenPgpSelf.java | 1 + .../EncryptedOpenPgpContentElement.java | 3 +- .../ox/element/OpenPgpContentElement.java | 2 +- .../ox/element/PublicKeysListElement.java | 3 +- .../OpenPgpContentElementProvider.java | 6 +- .../FileBasedOpenPgpMetadataStore.java | 1 + .../smackx/ox/util/OpenPgpPubSubUtil.java | 4 +- .../smackx/ox/OpenPgpElementTest.java | 1 + .../smackx/ox/OpenPgpStoreTest.java | 2 + .../ox/PainlessOpenPgpProviderTest.java | 1 + .../smackx/ox/PublicKeysListElementTest.java | 1 + .../ox_im/OXInstantMessagingManagerTest.java | 1 + smack-repl/build.gradle | 11 +- smack-resolver-dnsjava/build.gradle | 5 + smack-resolver-javax/build.gradle | 4 + .../smack/util/dns/javax/JavaxResolver.java | 3 +- smack-resolver-minidns-dox/build.gradle | 5 + smack-resolver-minidns/build.gradle | 5 + smack-sasl-javax/build.gradle | 4 + smack-sasl-provided/build.gradle | 5 + smack-streammanagement/build.gradle | 5 + smack-tcp/build.gradle | 5 + .../smack/tcp/XMPPTCPConnection.java | 3 +- .../smack/tcp/XmppTcpTransportModule.java | 24 +- smack-websocket-java11/build.gradle | 4 + smack-websocket-okhttp/build.gradle | 5 + smack-websocket/build.gradle | 5 + smack-xmlparser-stax/build.gradle | 7 +- smack-xmlparser-xpp3/build.gradle | 8 +- smack-xmlparser/build.gradle | 8 +- 136 files changed, 1161 insertions(+), 1220 deletions(-) create mode 100644 Makefile create mode 100644 build-logic/build.gradle create mode 100644 build-logic/settings.gradle create mode 100644 build-logic/src/main/groovy/org.igniterealtime.smack.android-boot-classpath-conventions.gradle create mode 100644 build-logic/src/main/groovy/org.igniterealtime.smack.android-conventions.gradle create mode 100644 build-logic/src/main/groovy/org.igniterealtime.smack.application-conventions.gradle create mode 100644 build-logic/src/main/groovy/org.igniterealtime.smack.global-conventions.gradle create mode 100644 build-logic/src/main/groovy/org.igniterealtime.smack.java-common-conventions.gradle create mode 100644 build-logic/src/main/groovy/org.igniterealtime.smack.javadoc-conventions.gradle delete mode 100644 resources/releasedocs/README.html diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 20c87d49e..5ddb006d2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,13 +6,13 @@ jobs: build: name: Build Smack - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: matrix: java: - - 11 + - 17 env: - PRIMARY_JAVA_VERSION: 11 + PRIMARY_JAVA_VERSION: 17 steps: - name: Checkout @@ -57,6 +57,17 @@ jobs: run: | sdkmanager "platforms;android-21" + # Workaround + - name: Create gradle.properties + run: | + cat <<-EOF > gradle.properties + # Workaround for https://github.com/CycloneDX/cyclonedx-gradle-plugin/issues/349 + # suggested at https://docs.gradle.org/current/userguide/upgrading_version_8.html#xml_parsing_now_requires_recent_parsers + systemProp.javax.xml.parsers.SAXParserFactory=com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl + systemProp.javax.xml.transform.TransformerFactory=com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl + systemProp.javax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl + EOF + # Testing - name: Gradle Check run: ./gradlew check --stacktrace @@ -72,10 +83,19 @@ jobs: # Test Coverage Report - name: Jacoco Test Coverage - if: ${{ matrix.java == env.PRIMARY_JAVA_VERSION }} - run: ./gradlew jacocoRootReport coveralls env: - COVERALLS_REPO_TOKEN: S2ecSJja2cKJa9yv45C8ZFPohXuRrTXKd + COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} + if: | + ${{ matrix.java == env.PRIMARY_JAVA_VERSION }} && + ${{ env.COVERALLS_REPO_TOKEN != '' }} + run: | + if [[ -z ${COVERALLS_REPO_TOKEN} ]]; then + echo WARNING: COVERALLS_REPO_TOKEN is empty + else + echo COVERALLS_REPO_TOKEN is not empty + fi + ./gradlew smack-java8-full:testCodeCoverageReport + ./gradlew smack-java8-full:coveralls # Upload build artifacts - name: Upload build artifacts diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..0621bf85f --- /dev/null +++ b/Makefile @@ -0,0 +1,30 @@ +GRADLE ?= ./gradlew + +.PHONY: all +all: check jacocoRootReport javadocAll sinttest + +.PHONY: codecov +codecov: + $(GRADLE) smack-java8-full:testCodeCoverageReport + echo "Report available at smack-java8-full/build/reports/jacoco/testCodeCoverageReport/html/index.html" + +.PHONY: check +check: + $(GRADLE) $@ + +.PHONY: eclipse +eclipse: + $(GRADLE) $@ + +.PHONY: sinttest +sinttest: + $(GRADLE) $@ + +.PHONY: jacocoRootReport +jacocoRootReport: + $(GRADLE) $@ + +.PHONY: javadocAll +javadocAll: + $(GRADLE) $@ + echo "Smack javadoc available at build/javadoc/index.html" diff --git a/build-logic/build.gradle b/build-logic/build.gradle new file mode 100644 index 000000000..795d644bd --- /dev/null +++ b/build-logic/build.gradle @@ -0,0 +1,16 @@ +plugins { + id 'groovy-gradle-plugin' +} + +repositories { + gradlePluginPortal() +} + +dependencies { + implementation "biz.aQute.bnd:biz.aQute.bnd.gradle:7.0.0" + implementation "io.freefair.gradle:maven-plugin:8.10" // for io.freefair.agregate-javadoc + implementation "me.champeau.jmh:jmh-gradle-plugin:0.7.2" + implementation "net.ltgt.gradle:gradle-errorprone-plugin:4.0.1" + implementation "gradle.plugin.org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.12.2" + implementation "ru.vyarus:gradle-animalsniffer-plugin:1.7.1" +} diff --git a/build-logic/settings.gradle b/build-logic/settings.gradle new file mode 100644 index 000000000..d082ce7e0 --- /dev/null +++ b/build-logic/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'smack-build-logic' diff --git a/build-logic/src/main/groovy/org.igniterealtime.smack.android-boot-classpath-conventions.gradle b/build-logic/src/main/groovy/org.igniterealtime.smack.android-boot-classpath-conventions.gradle new file mode 100644 index 000000000..c14cb3199 --- /dev/null +++ b/build-logic/src/main/groovy/org.igniterealtime.smack.android-boot-classpath-conventions.gradle @@ -0,0 +1,6 @@ +compileJava { + options.bootstrapClasspath = files(androidBootClasspath) +} +javadoc { + classpath += files(androidBootClasspath) +} diff --git a/build-logic/src/main/groovy/org.igniterealtime.smack.android-conventions.gradle b/build-logic/src/main/groovy/org.igniterealtime.smack.android-conventions.gradle new file mode 100644 index 000000000..6f92548d3 --- /dev/null +++ b/build-logic/src/main/groovy/org.igniterealtime.smack.android-conventions.gradle @@ -0,0 +1,10 @@ +plugins { + id 'ru.vyarus.animalsniffer' + id 'org.igniterealtime.smack.global-conventions' +} +dependencies { + signature "net.sf.androidscents.signature:android-api-level-${smackMinAndroidSdk}:5.0.1_r2@signature" +} +animalsniffer { + sourceSets = [sourceSets.main] +} diff --git a/build-logic/src/main/groovy/org.igniterealtime.smack.application-conventions.gradle b/build-logic/src/main/groovy/org.igniterealtime.smack.application-conventions.gradle new file mode 100644 index 000000000..fa4c7011e --- /dev/null +++ b/build-logic/src/main/groovy/org.igniterealtime.smack.application-conventions.gradle @@ -0,0 +1,12 @@ +plugins { + id 'application' +} + +application { + applicationDefaultJvmArgs = ["-enableassertions"] +} + +run { + // Pass all system properties down to the "application" run + systemProperties System.getProperties() +} diff --git a/build-logic/src/main/groovy/org.igniterealtime.smack.global-conventions.gradle b/build-logic/src/main/groovy/org.igniterealtime.smack.global-conventions.gradle new file mode 100644 index 000000000..00fbff953 --- /dev/null +++ b/build-logic/src/main/groovy/org.igniterealtime.smack.global-conventions.gradle @@ -0,0 +1,37 @@ +ext { + javaVersion = JavaVersion.VERSION_11 + javaMajor = javaVersion.getMajorVersion() + smackMinAndroidSdk = 21 + + androidBootClasspath = { getAndroidRuntimeJar() } +} + +repositories { + mavenLocal() + mavenCentral() +} + +def getAndroidRuntimeJar() { + def androidApiLevel = ext.smackMinAndroidSdk + def androidHome = getAndroidHome() + def androidJar = new File("$androidHome/platforms/android-${androidApiLevel}/android.jar") + if (androidJar.isFile()) { + return androidJar + } else { + throw new Exception("Can't find android.jar for API level ${androidApiLevel}. Please install corresponding SDK platform package") + } +} +def getAndroidJavadocOffline() { + def androidHome = getAndroidHome() + return androidHome.toString() + "/docs/reference" +} + +def getAndroidHome() { + def androidHomeEnv = System.getenv("ANDROID_HOME") + if (androidHomeEnv == null) { + throw new Exception("ANDROID_HOME environment variable is not set") + } + def androidHome = new File(androidHomeEnv) + if (!androidHome.isDirectory()) throw new Exception("Environment variable ANDROID_HOME is not pointing to a directory") + return androidHome +} diff --git a/build-logic/src/main/groovy/org.igniterealtime.smack.java-common-conventions.gradle b/build-logic/src/main/groovy/org.igniterealtime.smack.java-common-conventions.gradle new file mode 100644 index 000000000..e6a9ecbbf --- /dev/null +++ b/build-logic/src/main/groovy/org.igniterealtime.smack.java-common-conventions.gradle @@ -0,0 +1,373 @@ +plugins { + id 'biz.aQute.bnd.builder' + id 'checkstyle' + id 'com.github.kt3k.coveralls' + id 'eclipse' + id 'idea' + id 'jacoco' + id 'java' + id 'java-library' + id 'java-test-fixtures' + id 'maven-publish' + id 'net.ltgt.errorprone' + id 'signing' + + id 'jacoco-report-aggregation' + id 'test-report-aggregation' + + id 'org.igniterealtime.smack.global-conventions' + id 'org.igniterealtime.smack.javadoc-conventions' +} + +version readVersionFile() + +ext { + isSnapshot = version.endsWith('-SNAPSHOT') + gitCommit = getGitCommit() + rootConfigDir = new File(rootDir, 'config') + sonatypeCredentialsAvailable = project.hasProperty('sonatypeUsername') && project.hasProperty('sonatypePassword') + isReleaseVersion = !isSnapshot + isContinuousIntegrationEnvironment = Boolean.parseBoolean(System.getenv('CI')) + signingRequired = !(isSnapshot || isContinuousIntegrationEnvironment) + sonatypeSnapshotUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + sonatypeStagingUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' + builtDate = (new java.text.SimpleDateFormat("yyyy-MM-dd")).format(new Date()) + oneLineDesc = 'An Open Source XMPP (Jabber) client library' + + jxmppVersion = '[1.1.0-beta1, 1.1.999]' + miniDnsVersion = '[1.1.0-alpha3, 1.1.999]' + junitVersion = '5.9.2' + commonsIoVersion = '2.6' + bouncyCastleVersion = '1.73' + guavaVersion = '30.1-jre' + mockitoVersion = '5.13.0' + orgReflectionsVersion = '0.9.11' + + if (project.hasProperty("useSonatype")) { + useSonatype = project.getProperty("useSonatype").toBoolean() + } else { + // Default to true + useSonatype = true + } + + gplLicensedProjects = [ + ':smack-examples', + ':smack-omemo-signal', + ':smack-omemo-signal-integration-test', + ':smack-repl' + ].collect{ project(it) } +} + +group = 'org.igniterealtime.smack' + +java { + sourceCompatibility = javaVersion + targetCompatibility = sourceCompatibility +} + +eclipse { + classpath { + downloadJavadoc = true + } +} + +// Make all project's 'test' target depend on javadoc, so that +// javadoc is also linted. +test.dependsOn javadoc + +tasks.withType(JavaCompile) { + // Some systems may not have set their platform default + // converter to 'utf8', but we use unicode in our source + // files. Therefore ensure that javac uses unicode + options.encoding = "utf8" + options.compilerArgs = [ + '-Xlint:all', + // Set '-options' because a non-java7 javac will emit a + // warning if source/target is set to 1.7 and + // bootclasspath is *not* set. + '-Xlint:-options', + // TODO: Enable xlint serial + '-Xlint:-serial', + '-Werror', + ] +} +if (JavaVersion.current().isJava8Compatible()) { + tasks.withType(Javadoc) { + // The '-quiet' as second argument is actually a hack, + // since the one parameter addStringOption doesn't seem to + // work, we extra add '-quiet', which is added anyway by + // gradle. + // We disable 'missing' as we do most of javadoc checking via checkstyle. + options.addStringOption('Xdoclint:all,-missing', '-quiet') + // Abort on javadoc warnings. + // See JDK-8200363 (https://bugs.openjdk.java.net/browse/JDK-8200363) + // for information about the -Xwerror option. + options.addStringOption('Xwerror', '-quiet') + } +} + +if (JavaVersion.current().isJava9Compatible()) { + tasks.withType(JavaCompile) { + options.compilerArgs.addAll([ + '--release', javaMajor, + ]) + } +} + +jacoco { + toolVersion = "0.8.12" +} + +jacocoTestReport { + dependsOn test + reports { + xml.required = true + } +} + +dependencies { + testImplementation "org.junit.jupiter:junit-jupiter-api:$junitVersion" + testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junitVersion" + + testFixturesApi "org.junit.jupiter:junit-jupiter-api:$junitVersion" + testImplementation "org.junit.jupiter:junit-jupiter-params:$junitVersion" + testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junitVersion" + // https://stackoverflow.com/a/77274251/194894 + testRuntimeOnly "org.junit.platform:junit-platform-launcher:1.11.0" + + // The smack-extensions subproject uses mockito in its fest + // fixtures, and we want to have mockito also available in + // test, so we use API here. + testFixturesApi "org.mockito:mockito-core:${mockitoVersion}" + + testImplementation 'com.jamesmurty.utils:java-xmlbuilder:1.2' + + errorprone 'com.google.errorprone:error_prone_core:2.9.0' + errorproneJavac('com.google.errorprone:javac:9+181-r4173-1') +} + +test { + useJUnitPlatform() + + maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1 + + // Enable full stacktraces of failed tests. Especially handy + // for CI environments. + testLogging { + events "failed" + exceptionFormat "full" + } +} + +jar { + manifest { + attributes( + 'Implementation-Version': version, + 'Implementation-GitRevision': gitCommit, + 'Built-JDK': System.getProperty('java.version'), + 'Built-Gradle': gradle.gradleVersion, + 'Built-By': System.getProperty('user.name') + ) + } + + bundle { + bnd( + '-removeheaders': 'Tool, Bnd-*', + '-exportcontents': '*', + ) + } +} + +checkstyle { + toolVersion = '8.27' + + if (project in gplLicensedProjects) { + configProperties.checkstyleLicenseHeader = "${project.name}-gplv3-license-header" + } else { + configProperties.checkstyleLicenseHeader = "header" + } +} +task sourcesJar(type: Jar, dependsOn: classes) { + archiveClassifier = 'sources' + from sourceSets.main.allSource +} +task javadocJar(type: Jar, dependsOn: javadoc) { + archiveClassifier = 'javadoc' + from javadoc.destinationDir +} +task testsJar(type: Jar) { + archiveClassifier = 'tests' + from sourceSets.test.output +} +configurations { + testRuntime +} +artifacts { + // Add a 'testRuntime' configuration including the tests so that + // it can be consumed by other projects (smack-omemo-signal for + // example). See http://stackoverflow.com/a/21946676/194894 + testRuntime testsJar +} + +publishing { + publications { + mavenJava(MavenPublication) { + from components.java + artifact sourcesJar + artifact javadocJar + artifact testsJar + pom { + name = 'Smack' + packaging = 'jar' + inceptionYear = '2003' + url = 'http://www.igniterealtime.org/projects/jxmpp/' + afterEvaluate { + description = project.description + } + + issueManagement { + system = 'JIRA' + url = 'http://issues.igniterealtime.org/browse/SMACK' + } + + scm { + url = 'https://github.com/igniterealtime/Smack' + connection = 'scm:git:https://github.com/igniterealtime/Smack.git' + developerConnection = 'scm:git:https://github.com/igniterealtime/Smack.git' + } + + licenses { + if (project in gplLicensedProjects) { + license { + name = 'GNU General Public License, version 3 or any later version' + url = 'https://www.gnu.org/licenses/gpl.txt' + distribution = 'repo' + } + } else { + license { + name = 'The Apache Software License, Version 2.0' + url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution = 'repo' + } + } + } + + developers { + developer { + id = 'flow' + name = 'Florian Schmaus' + email = 'flow@igniterealtime.org' + } + } + } + } + } + repositories { + if (sonatypeCredentialsAvailable && useSonatype) { + maven { + url isSnapshot ? sonatypeSnapshotUrl : sonatypeStagingUrl + credentials { + username = sonatypeUsername + password = sonatypePassword + } + } + } + // Use + // gradle publish -P customRepoUrl=https://www.igniterealtime.org/archiva/repository/maven -P customRepoUsername=bamboo -P customRepoPassword=hidden -P useSonatype=false + // to deploy to this repo. + if (project.hasProperty("customRepoUrl")) { + maven { + name 'customRepo' + url customRepoUrl + if (project.hasProperty("customRepoUsername")) { + credentials { + username customRepoUsername + password customRepoPassword + } + } + } + } + } +} + +// Workaround for gpg signatory not supporting the 'required' option +// See https://github.com/gradle/gradle/issues/5064#issuecomment-381924984 +// Note what we use 'signing.gnupg.keyName' instead of 'signing.keyId'. +tasks.withType(Sign) { + onlyIf { + project.hasProperty('signing.gnupg.keyName') + } +} +signing { + required { signingRequired } + useGpgCmd() + sign publishing.publications.mavenJava +} + +tasks.withType(JavaCompile) { + options.errorprone { + disableWarningsInGeneratedCode = true + excludedPaths = ".*/jmh_generated/.*" + error( + "UnusedVariable", + "UnusedMethod", + "MethodCanBeStatic", + ) + errorproneArgs = [ + // Disable MissingCasesInEnumSwitch error prone check + // because this check is already done by javac as incomplete-switch. + '-Xep:MissingCasesInEnumSwitch:OFF', + '-Xep:StringSplitter:OFF', + '-Xep:JavaTimeDefaultTimeZone:OFF', + '-Xep:InlineMeSuggester:OFF', + ] + } +} + +// Work around https://github.com/gradle/gradle/issues/4046 +task copyJavadocDocFiles(type: Copy) { + from('src/javadoc') + into 'build/docs/javadoc' + include '**/doc-files/*.*' +} +javadoc.dependsOn copyJavadocDocFiles + +coveralls { + jacocoReportPath 'build/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml' +} + +def getGitCommit() { + def projectDirFile = new File("$projectDir") + + def cmd = 'git describe --always --tags --dirty=+' + def proc = cmd.execute(null, projectDirFile) + + def exitStatus = proc.waitFor() + if (exitStatus != 0) return "non-git build" + + def gitCommit = proc.text.trim() + assert !gitCommit.isEmpty() + gitCommit +} + +def getAndroidRuntimeJar() { + def androidHome = new File("$System.env.ANDROID_HOME") + if (!androidHome.isDirectory()) throw new Exception("ANDROID_HOME not found or set") + def androidJar = new File("$androidHome/platforms/android-$smackMinAndroidSdk/android.jar") + if (androidJar.isFile()) { + return androidJar + } else { + throw new Exception("Can't find android.jar for $smackMinAndroidSdk API. Please install corresponding SDK platform package") + } +} + +def readVersionFile() { + def versionFile = new File(rootDir, 'version') + if (!versionFile.isFile()) { + throw new Exception("Could not find version file") + } + if (versionFile.text.isEmpty()) { + throw new Exception("Version file does not contain a version") + } + versionFile.text.trim() +} diff --git a/build-logic/src/main/groovy/org.igniterealtime.smack.javadoc-conventions.gradle b/build-logic/src/main/groovy/org.igniterealtime.smack.javadoc-conventions.gradle new file mode 100644 index 000000000..61cb8f3c6 --- /dev/null +++ b/build-logic/src/main/groovy/org.igniterealtime.smack.javadoc-conventions.gradle @@ -0,0 +1,30 @@ +plugins { + // Javadoc linking requires repositories to bet configured. And + // those are declared in global-conventions, hence we add it here. + id 'org.igniterealtime.smack.global-conventions' +} + +if (JavaVersion.current().isJava8Compatible()) { + tasks.withType(Javadoc) { + // The '-quiet' as second argument is actually a hack, + // since the one parameter addStringOption doesn't seem to + // work, we extra add '-quiet', which is added anyway by + // gradle. + // We disable 'missing' as we do most of javadoc checking via checkstyle. + options.addStringOption('Xdoclint:all,-missing', '-quiet') + // Abort on javadoc warnings. + // See JDK-8200363 (https://bugs.openjdk.java.net/browse/JDK-8200363) + // for information about the -Xwerror option. + options.addStringOption('Xwerror', '-quiet') + } +} + +if (JavaVersion.current().isJava9Compatible()) { + tasks.withType(Javadoc) { + options.addStringOption('-release', javaMajor) + } +} + +tasks.withType(Javadoc) { + options.charSet = "UTF-8" +} diff --git a/build.gradle b/build.gradle index 8570669b9..13f9b12d7 100644 --- a/build.gradle +++ b/build.gradle @@ -1,346 +1,20 @@ -buildscript { - repositories { - gradlePluginPortal() - } -} - plugins { - id 'ru.vyarus.animalsniffer' version '1.5.0' - id 'net.ltgt.errorprone' version '1.3.0' - // Use e.g. "gradle taskTree" to show its dependency tree. - id 'com.dorongold.task-tree' version '1.5' - id 'com.github.kt3k.coveralls' version '2.10.2' - id 'biz.aQute.bnd.builder' version '6.4.0' + // The scalastyle plugin of smack-repl wants the root project to + // have a ideaProject task, so let's add one. + id 'idea' + + id 'org.igniterealtime.smack.javadoc-conventions' } ext { - java11Projects = [ - ':smack-examples', + javadocAllDir = new File(buildDir, 'javadoc') + integrationTestProjects = [ ':smack-integration-test', ':smack-omemo-signal-integration-test', - ':smack-repl', - ':smack-websocket-java11', - ].collect { project(it) } - java11Projects += getRootProject() - java8Projects = allprojects - java11Projects + ].collect{ project(it) } + javadocAllProjects = subprojects - integrationTestProjects } -configure (java8Projects) { - ext { - javaCompatilibity = JavaVersion.VERSION_1_8 - } -} - -configure (java11Projects) { - ext { - javaCompatilibity = JavaVersion.VERSION_11 - } -} - -allprojects { - apply plugin: 'java-library' - apply plugin: 'java-test-fixtures' - apply plugin: 'eclipse' - apply plugin: 'idea' - apply plugin: 'jacoco' - apply plugin: 'net.ltgt.errorprone' - - version readVersionFile() - - ext { - isSnapshot = version.endsWith('-SNAPSHOT') - gitCommit = getGitCommit() - javadocAllDir = new File(buildDir, 'javadoc') - documentationDir = new File(projectDir, 'documentation') - releasedocsDir = new File(buildDir, 'releasedocs') - rootConfigDir = new File(rootDir, 'config') - sonatypeCredentialsAvailable = project.hasProperty('sonatypeUsername') && project.hasProperty('sonatypePassword') - isReleaseVersion = !isSnapshot - isContinuousIntegrationEnvironment = Boolean.parseBoolean(System.getenv('CI')) - signingRequired = !(isSnapshot || isContinuousIntegrationEnvironment) - sonatypeSnapshotUrl = 'https://oss.sonatype.org/content/repositories/snapshots' - sonatypeStagingUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - // Returns only the date in yyyy-MM-dd format, as otherwise, with - // hh:mm:ss information, the manifest files would change with every - // build, causing unnecessary rebuilds. - builtDate = (new java.text.SimpleDateFormat("yyyy-MM-dd")).format(new Date()) - oneLineDesc = 'An Open Source XMPP (Jabber) client library' - integrationTestProjects = [ - ':smack-integration-test', - ':smack-omemo-signal-integration-test', - ].collect{ project(it) } - javadocAllProjects = subprojects - integrationTestProjects - // A dirty hack used for Gradle's jacoco plugin, since is not - // hable to handle the case when a (sub)project has no unit - // tests. :-( - projectsWithoutUnitTests = [ - ':smack-android', - ':smack-android-extensions', - ':smack-bosh', - ':smack-debug', - ':smack-debug-slf4j', - ':smack-java8', - ':smack-jingle-old', - ':smack-resolver-dnsjava', - ':smack-resolver-javax', - ':smack-resolver-minidns', - ':smack-omemo-signal-integration-test', - ].collect{ project(it) } - projectsWithUnitTests = subprojects - projectsWithoutUnitTests - androidProjects = [ - ':smack-tcp', - ':smack-bosh', - ':smack-core', - ':smack-im', - ':smack-resolver-minidns', - ':smack-sasl-provided', - ':smack-extensions', - ':smack-experimental', - ':smack-omemo', - ':smack-omemo-signal', - ':smack-openpgp', - ':smack-xmlparser', - ':smack-xmlparser-xpp3', - ].collect{ project(it) } - androidBootClasspathProjects = [ - ':smack-android', - ':smack-android-extensions', - ].collect{ project(it) } - androidOptionalProjects = [ - ':smack-tcp', - ':smack-extensions', - ':smack-experimental', - ':smack-bosh', - ':smack-omemo', - ':smack-omemo-signal', - ].collect{ project(it) } - gplLicensedProjects = [ - ':smack-examples', - ':smack-omemo-signal', - ':smack-omemo-signal-integration-test', - ':smack-repl' - ].collect{ project(it) } - // Lazily evaluate the Android bootClasspath and offline - // Javadoc using a closure, so that targets which do not - // require it are still able to succeed without an Android - // SDK. - androidBootClasspath = { getAndroidRuntimeJar() } - androidJavadocOffline = { getAndroidJavadocOffline() } - junit4Projects = [ - ':smack-core', - ':smack-im', - ':smack-omemo', - ':smack-omemo-signal', - ':smack-openpgp', - ].collect { project(it) } - - // When using dynamic versions for those, do *not* use [1.0, - // 2.0), since this will also pull in 2.0-alpha1. Instead use - // [1.0, 1.0.99]. - // See also: - // - https://issues.apache.org/jira/browse/MNG-6232 - // - https://issues.igniterealtime.org/browse/SMACK-858 - jxmppVersion = '[1.1.0-beta1, 1.1.999]' - miniDnsVersion = '[1.1.0-alpha3, 1.1.999]' - smackMinAndroidSdk = 21 - junitVersion = '5.7.1' - commonsIoVersion = '2.6' - bouncyCastleVersion = '1.73' - guavaVersion = '30.1-jre' - mockitoVersion = '3.7.7' - orgReflectionsVersion = '0.9.11' - - if (project.hasProperty("useSonatype")) { - useSonatype = project.getProperty("useSonatype").toBoolean() - } else { - // Default to true - useSonatype = true - } - javaMajor = javaCompatilibity.getMajorVersion() - } - group = 'org.igniterealtime.smack' - sourceCompatibility = javaCompatilibity - targetCompatibility = sourceCompatibility - - test { - useJUnitPlatform() - - maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1 - - // Enable full stacktraces of failed tests. Especially handy - // for environments like Travis. - testLogging { - events "failed" - exceptionFormat "full" - } - } - - ext.sharedManifest = manifest { - attributes('Implementation-Version': version, - 'Implementation-GitRevision': ext.gitCommit, - 'Built-Date': ext.builtDate, - 'Built-JDK': System.getProperty('java.version'), - 'Built-Gradle': gradle.gradleVersion, - 'Built-By': System.getProperty('user.name') - ) - } - - eclipse { - classpath { - downloadJavadoc = true - } - } - - repositories { - mavenLocal() - mavenCentral() - } - - tasks.withType(JavaCompile) { - // Some systems may not have set their platform default - // converter to 'utf8', but we use unicode in our source - // files. Therefore ensure that javac uses unicode - options.encoding = 'UTF-8' - options.compilerArgs = [ - '-Xlint:all', - // Set '-options' because a non-java7 javac will emit a - // warning if source/target is set to 1.7 and - // bootclasspath is *not* set. - // TODO implement a sound heuristic to determine a java7 - // rt.jar on the build host. And if none is found, - // fallback to using a environment variable, - // e.g. JAVA7_HOME. See SMACK-651. - '-Xlint:-options', - '-Werror', - ] - options.errorprone { - error( - "UnusedVariable", - "UnusedMethod", - "MethodCanBeStatic", - ) - errorproneArgs = [ - // Disable errorprone checks - '-Xep:TypeParameterUnusedInFormals:OFF', - // Disable errorpone StringSplitter check, as it - // recommends using Splitter from Guava, which we don't - // have (nor want to use in Smack). - '-Xep:StringSplitter:OFF', - '-Xep:JdkObsolete:OFF', - // Disabled because sinttest re-uses BeforeClass from junit. - // TODO: change sinttest so that it has it's own - // BeforeClass and re-enable this check. - '-Xep:JUnit4ClassAnnotationNonStatic:OFF', - // Disabled but should be re-enabled at some point - //'-Xep:InconsistentCapitalization:OFF', - '-Xep:MixedMutabilityReturnType:OFF', - // TODO: Re-enable once Smack's minimum Android SDK level is 26 or higher. - '-Xep:JavaUtilDate:OFF', - ] - } - } - - tasks.withType(ScalaCompile) { - scalaCompileOptions.additionalParameters = [ - '-Xfatal-warnings', - '-feature', - ] - } - - jacoco { - toolVersion = "0.8.6" - } - - jacocoTestReport { - dependsOn test - getSourceDirectories().setFrom(project.files(sourceSets.main.allSource.srcDirs)) - getClassDirectories().setFrom(project.files(sourceSets.main.output)) - reports { - xml.enabled true - } - } - - if (JavaVersion.current().isJava8Compatible()) { - tasks.withType(Javadoc) { - // The '-quiet' as second argument is actually a hack, - // since the one parameter addStringOption doesn't seem to - // work, we extra add '-quiet', which is added anyway by - // gradle. - // TODO: This enables all doclint check but - // 'missing'. Re-enable 'missing' once every public API in - // Smack has a javadoc comment. - options.addStringOption('Xdoclint:accessibility,html,reference,syntax', '-quiet') - - // Treat warnings as errors. - // See also https://bugs.openjdk.java.net/browse/JDK-8200363 - options.addStringOption('Xwerror', '-quiet') - } - } - - if (JavaVersion.current().isJava9Compatible()) { - tasks.withType(Javadoc) { - options.addStringOption('-release', javaMajor) - - // The -no-modules-directories javadoc option was removed in Java 13 - // See https://bugs.openjdk.java.net/browse/JDK-8215582 - if (JavaVersion.current() < JavaVersion.VERSION_13) { - // Fix for javadoc search. If not set, the search result would direct to - // javadoc/undefined/org/jivesoftware/smack/altconnections/HttpLookupMethod.html - // instead of - // javadoc/org/jivesoftware/smack/altconnections/HttpLookupMethod.html - // https://stackoverflow.com/a/53732633/194894 - options.addBooleanOption("-no-module-directories", true) - } - } - tasks.withType(JavaCompile) { - options.compilerArgs.addAll([ - '--release', javaMajor, - ]) - } - } - -tasks.withType(Javadoc) { - options.charSet = "UTF-8" - options.encoding = 'UTF-8' - } - - dependencies { - testFixturesApi "org.junit.jupiter:junit-jupiter-api:$junitVersion" - testImplementation "org.junit.jupiter:junit-jupiter-params:$junitVersion" - testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junitVersion" - // https://stackoverflow.com/a/77274251/194894 - testRuntimeOnly "org.junit.platform:junit-platform-launcher" - - // The smack-extensions subproject uses mockito in its fest - // fixtures, and we want to have mockito also available in - // test, so we use API here. - testFixturesApi "org.mockito:mockito-core:${mockitoVersion}" - - // To mock final classes - testImplementation "org.mockito:mockito-inline:${mockitoVersion}" - testImplementation 'com.jamesmurty.utils:java-xmlbuilder:1.2' - - errorprone 'com.google.errorprone:error_prone_core:2.5.1' - errorproneJavac('com.google.errorprone:javac:9+181-r4173-1') - } - - // Make all project's 'test' target depend on javadoc, so that - // javadoc is also linted. - test { dependsOn javadoc } -} - -configure (junit4Projects) { - dependencies { - testImplementation "org.junit.vintage:junit-vintage-engine:$junitVersion" - } -} - -// We need to evaluate the child projects first because -// - javadocAll needs the smack-core child to have already resolved -// the jXMPP/MiniDNS dependencies, so that we can the resolved -// version to link to those project's javadoc. -// - We use the child's project description as description for the -// Maven POM. evaluationDependsOnChildren() task javadocAll(type: Javadoc) { source javadocAllProjects.collect {project -> @@ -389,286 +63,6 @@ task javadocAll(type: Javadoc) { } } -import org.apache.tools.ant.filters.ReplaceTokens -task prepareReleasedocs(type: Copy) { - from 'resources/releasedocs' - into releasedocsDir - filter(ReplaceTokens, tokens: [version: version, releasedate: builtDate, targetCompatibility: targetCompatibility.toString()]) -} - -task distributionZip(type: Zip, dependsOn: [javadocAll, prepareReleasedocs]) { - classifier builtDate - into ('javadoc') { - from(javadocAllDir) - } - into ('releasedocs') { - from(releasedocsDir) - } - into ('releasedocs/documentation') { - from(documentationDir) - } -} - -task maybeCheckForSnapshotDependencies { - // Don't check for Snapshot dependencies if this is a snapshot. - onlyIf { isReleaseVersion } - // Run in the execution phase, not in configuration phase, as the - // 'each' forces the runtime configuration to be resolved, which - // causes "Cannot change dependencies of configuration after it - // has been included in dependency resolution." errors. - // See https://discuss.gradle.org/t/23153 - doLast { - allprojects { project -> - project.configurations.runtime.each { - if (it.toString().contains("-SNAPSHOT")) - throw new Exception("Release build contains snapshot dependencies: " + it) - } - } - } -} - -test { dependsOn maybeCheckForSnapshotDependencies } - -jar { - // Root project should not create empty jar artifact - enabled = false -} - -// Disable upload archives for the root project -uploadArchives.enabled = false - -description = """\ -Smack ${version} -${oneLineDesc}.""" - -subprojects { - apply plugin: 'maven-publish' - apply plugin: 'signing' - apply plugin: 'checkstyle' - apply plugin: 'biz.aQute.bnd.builder' - - checkstyle { - toolVersion = '8.27' - } - task sourcesJar(type: Jar, dependsOn: classes) { - classifier = 'sources' - from sourceSets.main.allSource - } - task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from javadoc.destinationDir - } - task testsJar(type: Jar, dependsOn: testClasses) { - classifier = 'tests' - from sourceSets.test.output - } - - artifacts { - // See http://stackoverflow.com/a/21946676/194894 - testRuntime testsJar - } - - publishing { - publications { - mavenJava(MavenPublication) { - from components.java - artifact sourcesJar - artifact javadocJar - artifact testsJar - pom { - name = 'Smack' - packaging = 'jar' - inceptionYear = '2003' - url = 'http://www.igniterealtime.org/projects/smack/' - description = project.description - - issueManagement { - system = 'JIRA' - url = 'https://igniterealtime.org/issues/browse/SMACK' - } - - scm { - url = 'https://github.com/igniterealtime/Smack' - connection = 'scm:git:https://github.com/igniterealtime/Smack.git' - developerConnection = 'scm:git:https://github.com/igniterealtime/Smack.git' - } - - developers { - developer { - id = 'flow' - name = 'Florian Schmaus' - email = 'flow@igniterealtime.org' - } - } - } - } - } - repositories { - if (sonatypeCredentialsAvailable && useSonatype) { - maven { - url isSnapshot ? sonatypeSnapshotUrl : sonatypeStagingUrl - credentials { - username = sonatypeUsername - password = sonatypePassword - } - } - } - // Use - // gradle publish -P customRepoUrl=https://www.igniterealtime.org/archiva/repository/maven -P customRepoUsername=bamboo -P customRepoPassword=hidden -P useSonatype=false - // to deploy to this repo. - if (project.hasProperty("customRepoUrl")) { - maven { - name 'customRepo' - url customRepoUrl - if (project.hasProperty("customRepoUsername")) { - credentials { - username customRepoUsername - password customRepoPassword - } - } - } - } - } - } - rootProject.distributionZip { - dependsOn build - from(buildDir) { - include "$libsDirName/*${version}.jar" - include "$libsDirName/*${version}-javadoc.jar" - include "$libsDirName/*${version}-sources.jar" - } - } - - // Workaround for gpg signatory not supporting the 'required' option - // See https://github.com/gradle/gradle/issues/5064#issuecomment-381924984 - // Note what we use 'signing.gnupg.keyName' instead of 'signing.keyId'. - tasks.withType(Sign) { - onlyIf { - project.hasProperty('signing.gnupg.keyName') - } - } - signing { - useGpgCmd() - required { signingRequired } - sign publishing.publications.mavenJava - } - - // Work around https://github.com/gradle/gradle/issues/4046 - task copyJavadocDocFiles(type: Copy) { - from('src/javadoc') - into 'build/docs/javadoc' - include '**/doc-files/*.*' - } - javadoc.dependsOn copyJavadocDocFiles - - // Make sure root projects 'javadocAll' depends on the - // subproject's javadoc, to ensure that all all doc-files/ are - // generated and up-to-date. Obviously this means that the - // javadocAll task will also create the individual javadoc's of the - // subprojects. - javadocAll.dependsOn javadoc -} - -// The smack-java8-full project generates the dot and png files of the -// current state graph. Ensure they are generated before copied. -configure (project(':smack-java8-full')) { - copyJavadocDocFiles.dependsOn convertModularXmppClientToServerConnectionStateGraphDotToPng -} - -configure (androidProjects + androidBootClasspathProjects) { - apply plugin: 'ru.vyarus.animalsniffer' - dependencies { - signature "net.sf.androidscents.signature:android-api-level-${smackMinAndroidSdk}:5.0.1_r2@signature" - } - animalsniffer { - sourceSets = [sourceSets.main] - } -} - -subprojects*.jar { - manifest { - from sharedManifest - } - bundle { - bnd( - '-removeheaders': 'Tool, Bnd-*', - '-exportcontents': '*', - ) - } -} - -configure(subprojects - gplLicensedProjects) { - checkstyle { - configProperties.checkstyleLicenseHeader = "header" - } - publishing { - publications { - mavenJava(MavenPublication) { - pom { - licenses { - license { - name = 'The Apache Software License, Version 2.0' - url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution = 'repo' - } - } - } - } - } - } -} - -configure(gplLicensedProjects) { - checkstyle { - configProperties.checkstyleLicenseHeader = "${project.name}-gplv3-license-header" - } - publishing { - publications { - mavenJava(MavenPublication) { - pom { - licenses { - license { - name = 'GNU General Public License, version 3 or any later version' - url = 'https://www.gnu.org/licenses/gpl.txt' - distribution = 'repo' - } - } - } - } - } - } -} - -configure(androidBootClasspathProjects) { - compileJava { - options.bootstrapClasspath = files(androidBootClasspath) - } - javadoc { - classpath += files(androidBootClasspath) - } -} - -apply plugin: "com.github.kt3k.coveralls" -coveralls { - sourceDirs = files(subprojects.sourceSets.main.allSource.srcDirs).files.absolutePath -} - -task jacocoRootReport(type: org.gradle.testing.jacoco.tasks.JacocoReport) { - dependsOn = projectsWithUnitTests.jacocoTestReport - getSourceDirectories().setFrom(files(projectsWithUnitTests.sourceSets.main.allSource.srcDirs)) - getClassDirectories().setFrom(files(projectsWithUnitTests.sourceSets.main.output)) - getExecutionData().setFrom(files(projectsWithUnitTests.jacocoTestReport.executionData)) - reports { - xml.enabled true - xml.destination file("${buildDir}/reports/jacoco/test/jacocoTestReport.xml") - } - // We could remove the following setOnlyIf line, but then - // jacocoRootReport would silently be SKIPPED if something with - // the projectsWithUnitTests is wrong (e.g. a project is missing - // in there). - setOnlyIf { true } -} - task integrationTest { description 'Verify correct functionality of Smack by running some integration tests.' dependsOn project(':smack-integration-test').tasks.run @@ -676,7 +70,7 @@ task integrationTest { task omemoSignalIntTest { description 'Run integration tests of the smack-omemo module in combination with smack-omemo-signal.' - dependsOn project(':smack-omemo-signal-integration-test').tasks.run + dependsOn 'smack-omemo-signal-integration-test:run' } task sinttestAll { @@ -687,70 +81,6 @@ task sinttestAll { ]} } -def getGitCommit() { - def projectDirFile = new File("$projectDir") - def dotGit = new File(projectDirFile, ".git") - if (!dotGit.isDirectory()) return 'non-git build' - - def cmd = 'git describe --always --tags --dirty=+' - def proc = cmd.execute(null, projectDirFile) - proc.waitForOrKill(10 * 1000) - - def gitCommit = proc.text.trim() - assert !gitCommit.isEmpty() - - def srCmd = 'git symbolic-ref --short HEAD' - def srProc = srCmd.execute(null, projectDirFile) - srProc.waitForOrKill(10 * 1000) - if (srProc.exitValue() == 0) { - // Only add the information if the git command was - // successful. There may be no symbolic reference for HEAD if - // e.g. in detached mode. - def symbolicReference = srProc.text.trim() - assert !symbolicReference.isEmpty() - gitCommit += "-$symbolicReference" - } - - gitCommit -} - -def getAndroidRuntimeJar() { - def androidApiLevel = ext.smackMinAndroidSdk - def androidHome = getAndroidHome() - def androidJar = new File("$androidHome/platforms/android-${androidApiLevel}/android.jar") - if (androidJar.isFile()) { - return androidJar - } else { - throw new Exception("Can't find android.jar for API level ${androidApiLevel}. Please install corresponding SDK platform package") - } -} - -def getAndroidJavadocOffline() { - def androidHome = getAndroidHome() - return androidHome.toString() + "/docs/reference" -} - -def getAndroidHome() { - def androidHomeEnv = System.getenv("ANDROID_HOME") - if (androidHomeEnv == null) { - throw new Exception("ANDROID_HOME environment variable is not set") - } - def androidHome = new File(androidHomeEnv) - if (!androidHome.isDirectory()) throw new Exception("Environment variable ANDROID_HOME is not pointing to a directory") - return androidHome -} - -def readVersionFile() { - def versionFile = new File(rootDir, 'version') - if (!versionFile.isFile()) { - throw new Exception("Could not find version file") - } - if (versionFile.text.isEmpty()) { - throw new Exception("Version file does not contain a version") - } - versionFile.text.trim() -} - def getResolvedVersion(queriedProject = 'smack-core', component) { def configuration = project(queriedProject) .configurations diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e708b1c023ec8b20f512888fe07c5bd3ff77bb8f..a4b76b9530d66f5e68d973ea569d8e19de379189 100644 GIT binary patch literal 43583 zcma&N1CXTcmMvW9vTb(Rwr$&4wr$(C?dmSu>@vG-+vuvg^_??!{yS%8zW-#zn-LkA z5&1^$^{lnmUON?}LBF8_K|(?T0Ra(xUH{($5eN!MR#ZihR#HxkUPe+_R8Cn`RRs(P z_^*#_XlXmGv7!4;*Y%p4nw?{bNp@UZHv1?Um8r6)Fei3p@ClJn0ECfg1hkeuUU@Or zDaPa;U3fE=3L}DooL;8f;P0ipPt0Z~9P0)lbStMS)ag54=uL9ia-Lm3nh|@(Y?B`; zx_#arJIpXH!U{fbCbI^17}6Ri*H<>OLR%c|^mh8+)*h~K8Z!9)DPf zR2h?lbDZQ`p9P;&DQ4F0sur@TMa!Y}S8irn(%d-gi0*WxxCSk*A?3lGh=gcYN?FGl z7D=Js!i~0=u3rox^eO3i@$0=n{K1lPNU zwmfjRVmLOCRfe=seV&P*1Iq=^i`502keY8Uy-WNPwVNNtJFx?IwAyRPZo2Wo1+S(xF37LJZ~%i)kpFQ3Fw=mXfd@>%+)RpYQLnr}B~~zoof(JVm^^&f zxKV^+3D3$A1G;qh4gPVjhrC8e(VYUHv#dy^)(RoUFM?o%W-EHxufuWf(l*@-l+7vt z=l`qmR56K~F|v<^Pd*p~1_y^P0P^aPC##d8+HqX4IR1gu+7w#~TBFphJxF)T$2WEa zxa?H&6=Qe7d(#tha?_1uQys2KtHQ{)Qco)qwGjrdNL7thd^G5i8Os)CHqc>iOidS} z%nFEDdm=GXBw=yXe1W-ShHHFb?Cc70+$W~z_+}nAoHFYI1MV1wZegw*0y^tC*s%3h zhD3tN8b=Gv&rj}!SUM6|ajSPp*58KR7MPpI{oAJCtY~JECm)*m_x>AZEu>DFgUcby z1Qaw8lU4jZpQ_$;*7RME+gq1KySGG#Wql>aL~k9tLrSO()LWn*q&YxHEuzmwd1?aAtI zBJ>P=&$=l1efe1CDU;`Fd+_;&wI07?V0aAIgc(!{a z0Jg6Y=inXc3^n!U0Atk`iCFIQooHqcWhO(qrieUOW8X(x?(RD}iYDLMjSwffH2~tB z)oDgNBLB^AJBM1M^c5HdRx6fBfka`(LD-qrlh5jqH~);#nw|iyp)()xVYak3;Ybik z0j`(+69aK*B>)e_p%=wu8XC&9e{AO4c~O1U`5X9}?0mrd*m$_EUek{R?DNSh(=br# z#Q61gBzEpmy`$pA*6!87 zSDD+=@fTY7<4A?GLqpA?Pb2z$pbCc4B4zL{BeZ?F-8`s$?>*lXXtn*NC61>|*w7J* z$?!iB{6R-0=KFmyp1nnEmLsA-H0a6l+1uaH^g%c(p{iT&YFrbQ$&PRb8Up#X3@Zsk zD^^&LK~111%cqlP%!_gFNa^dTYT?rhkGl}5=fL{a`UViaXWI$k-UcHJwmaH1s=S$4 z%4)PdWJX;hh5UoK?6aWoyLxX&NhNRqKam7tcOkLh{%j3K^4Mgx1@i|Pi&}<^5>hs5 zm8?uOS>%)NzT(%PjVPGa?X%`N2TQCKbeH2l;cTnHiHppPSJ<7y-yEIiC!P*ikl&!B z%+?>VttCOQM@ShFguHVjxX^?mHX^hSaO_;pnyh^v9EumqSZTi+#f&_Vaija0Q-e*| z7ulQj6Fs*bbmsWp{`auM04gGwsYYdNNZcg|ph0OgD>7O}Asn7^Z=eI>`$2*v78;sj-}oMoEj&@)9+ycEOo92xSyY344^ z11Hb8^kdOvbf^GNAK++bYioknrpdN>+u8R?JxG=!2Kd9r=YWCOJYXYuM0cOq^FhEd zBg2puKy__7VT3-r*dG4c62Wgxi52EMCQ`bKgf*#*ou(D4-ZN$+mg&7$u!! z-^+Z%;-3IDwqZ|K=ah85OLwkO zKxNBh+4QHh)u9D?MFtpbl)us}9+V!D%w9jfAMYEb>%$A;u)rrI zuBudh;5PN}_6J_}l55P3l_)&RMlH{m!)ai-i$g)&*M`eN$XQMw{v^r@-125^RRCF0 z^2>|DxhQw(mtNEI2Kj(;KblC7x=JlK$@78`O~>V!`|1Lm-^JR$-5pUANAnb(5}B}JGjBsliK4& zk6y(;$e&h)lh2)L=bvZKbvh@>vLlreBdH8No2>$#%_Wp1U0N7Ank!6$dFSi#xzh|( zRi{Uw%-4W!{IXZ)fWx@XX6;&(m_F%c6~X8hx=BN1&q}*( zoaNjWabE{oUPb!Bt$eyd#$5j9rItB-h*5JiNi(v^e|XKAj*8(k<5-2$&ZBR5fF|JA z9&m4fbzNQnAU}r8ab>fFV%J0z5awe#UZ|bz?Ur)U9bCIKWEzi2%A+5CLqh?}K4JHi z4vtM;+uPsVz{Lfr;78W78gC;z*yTch~4YkLr&m-7%-xc ztw6Mh2d>_iO*$Rd8(-Cr1_V8EO1f*^@wRoSozS) zy1UoC@pruAaC8Z_7~_w4Q6n*&B0AjOmMWa;sIav&gu z|J5&|{=a@vR!~k-OjKEgPFCzcJ>#A1uL&7xTDn;{XBdeM}V=l3B8fE1--DHjSaxoSjNKEM9|U9#m2<3>n{Iuo`r3UZp;>GkT2YBNAh|b z^jTq-hJp(ebZh#Lk8hVBP%qXwv-@vbvoREX$TqRGTgEi$%_F9tZES@z8Bx}$#5eeG zk^UsLBH{bc2VBW)*EdS({yw=?qmevwi?BL6*=12k9zM5gJv1>y#ML4!)iiPzVaH9% zgSImetD@dam~e>{LvVh!phhzpW+iFvWpGT#CVE5TQ40n%F|p(sP5mXxna+Ev7PDwA zamaV4m*^~*xV+&p;W749xhb_X=$|LD;FHuB&JL5?*Y2-oIT(wYY2;73<^#46S~Gx| z^cez%V7x$81}UWqS13Gz80379Rj;6~WdiXWOSsdmzY39L;Hg3MH43o*y8ibNBBH`(av4|u;YPq%{R;IuYow<+GEsf@R?=@tT@!}?#>zIIn0CoyV!hq3mw zHj>OOjfJM3F{RG#6ujzo?y32m^tgSXf@v=J$ELdJ+=5j|=F-~hP$G&}tDZsZE?5rX ztGj`!S>)CFmdkccxM9eGIcGnS2AfK#gXwj%esuIBNJQP1WV~b~+D7PJTmWGTSDrR` zEAu4B8l>NPuhsk5a`rReSya2nfV1EK01+G!x8aBdTs3Io$u5!6n6KX%uv@DxAp3F@{4UYg4SWJtQ-W~0MDb|j-$lwVn znAm*Pl!?Ps&3wO=R115RWKb*JKoexo*)uhhHBncEDMSVa_PyA>k{Zm2(wMQ(5NM3# z)jkza|GoWEQo4^s*wE(gHz?Xsg4`}HUAcs42cM1-qq_=+=!Gk^y710j=66(cSWqUe zklbm8+zB_syQv5A2rj!Vbw8;|$@C!vfNmNV!yJIWDQ>{+2x zKjuFX`~~HKG~^6h5FntRpnnHt=D&rq0>IJ9#F0eM)Y-)GpRjiN7gkA8wvnG#K=q{q z9dBn8_~wm4J<3J_vl|9H{7q6u2A!cW{bp#r*-f{gOV^e=8S{nc1DxMHFwuM$;aVI^ zz6A*}m8N-&x8;aunp1w7_vtB*pa+OYBw=TMc6QK=mbA-|Cf* zvyh8D4LRJImooUaSb7t*fVfih<97Gf@VE0|z>NcBwBQze);Rh!k3K_sfunToZY;f2 z^HmC4KjHRVg+eKYj;PRN^|E0>Gj_zagfRbrki68I^#~6-HaHg3BUW%+clM1xQEdPYt_g<2K+z!$>*$9nQ>; zf9Bei{?zY^-e{q_*|W#2rJG`2fy@{%6u0i_VEWTq$*(ZN37|8lFFFt)nCG({r!q#9 z5VK_kkSJ3?zOH)OezMT{!YkCuSSn!K#-Rhl$uUM(bq*jY? zi1xbMVthJ`E>d>(f3)~fozjg^@eheMF6<)I`oeJYx4*+M&%c9VArn(OM-wp%M<-`x z7sLP1&3^%Nld9Dhm@$3f2}87!quhI@nwd@3~fZl_3LYW-B?Ia>ui`ELg z&Qfe!7m6ze=mZ`Ia9$z|ARSw|IdMpooY4YiPN8K z4B(ts3p%2i(Td=tgEHX z0UQ_>URBtG+-?0E;E7Ld^dyZ;jjw0}XZ(}-QzC6+NN=40oDb2^v!L1g9xRvE#@IBR zO!b-2N7wVfLV;mhEaXQ9XAU+>=XVA6f&T4Z-@AX!leJ8obP^P^wP0aICND?~w&NykJ#54x3_@r7IDMdRNy4Hh;h*!u(Ol(#0bJdwEo$5437-UBjQ+j=Ic>Q2z` zJNDf0yO6@mr6y1#n3)s(W|$iE_i8r@Gd@!DWDqZ7J&~gAm1#~maIGJ1sls^gxL9LLG_NhU!pTGty!TbhzQnu)I*S^54U6Yu%ZeCg`R>Q zhBv$n5j0v%O_j{QYWG!R9W?5_b&67KB$t}&e2LdMvd(PxN6Ir!H4>PNlerpBL>Zvyy!yw z-SOo8caEpDt(}|gKPBd$qND5#a5nju^O>V&;f890?yEOfkSG^HQVmEbM3Ugzu+UtH zC(INPDdraBN?P%kE;*Ae%Wto&sgw(crfZ#Qy(<4nk;S|hD3j{IQRI6Yq|f^basLY; z-HB&Je%Gg}Jt@={_C{L$!RM;$$|iD6vu#3w?v?*;&()uB|I-XqEKqZPS!reW9JkLewLb!70T7n`i!gNtb1%vN- zySZj{8-1>6E%H&=V}LM#xmt`J3XQoaD|@XygXjdZ1+P77-=;=eYpoEQ01B@L*a(uW zrZeZz?HJsw_4g0vhUgkg@VF8<-X$B8pOqCuWAl28uB|@r`19DTUQQsb^pfqB6QtiT z*`_UZ`fT}vtUY#%sq2{rchyfu*pCg;uec2$-$N_xgjZcoumE5vSI{+s@iLWoz^Mf; zuI8kDP{!XY6OP~q5}%1&L}CtfH^N<3o4L@J@zg1-mt{9L`s^z$Vgb|mr{@WiwAqKg zp#t-lhrU>F8o0s1q_9y`gQNf~Vb!F%70f}$>i7o4ho$`uciNf=xgJ>&!gSt0g;M>*x4-`U)ysFW&Vs^Vk6m%?iuWU+o&m(2Jm26Y(3%TL; zA7T)BP{WS!&xmxNw%J=$MPfn(9*^*TV;$JwRy8Zl*yUZi8jWYF>==j~&S|Xinsb%c z2?B+kpet*muEW7@AzjBA^wAJBY8i|#C{WtO_or&Nj2{=6JTTX05}|H>N2B|Wf!*3_ z7hW*j6p3TvpghEc6-wufFiY!%-GvOx*bZrhZu+7?iSrZL5q9}igiF^*R3%DE4aCHZ zqu>xS8LkW+Auv%z-<1Xs92u23R$nk@Pk}MU5!gT|c7vGlEA%G^2th&Q*zfg%-D^=f z&J_}jskj|Q;73NP4<4k*Y%pXPU2Thoqr+5uH1yEYM|VtBPW6lXaetokD0u z9qVek6Q&wk)tFbQ8(^HGf3Wp16gKmr>G;#G(HRBx?F`9AIRboK+;OfHaLJ(P>IP0w zyTbTkx_THEOs%Q&aPrxbZrJlio+hCC_HK<4%f3ZoSAyG7Dn`=X=&h@m*|UYO-4Hq0 z-Bq&+Ie!S##4A6OGoC~>ZW`Y5J)*ouaFl_e9GA*VSL!O_@xGiBw!AF}1{tB)z(w%c zS1Hmrb9OC8>0a_$BzeiN?rkPLc9%&;1CZW*4}CDDNr2gcl_3z+WC15&H1Zc2{o~i) z)LLW=WQ{?ricmC`G1GfJ0Yp4Dy~Ba;j6ZV4r{8xRs`13{dD!xXmr^Aga|C=iSmor% z8hi|pTXH)5Yf&v~exp3o+sY4B^^b*eYkkCYl*T{*=-0HniSA_1F53eCb{x~1k3*`W zr~};p1A`k{1DV9=UPnLDgz{aJH=-LQo<5%+Em!DNN252xwIf*wF_zS^!(XSm(9eoj z=*dXG&n0>)_)N5oc6v!>-bd(2ragD8O=M|wGW z!xJQS<)u70m&6OmrF0WSsr@I%T*c#Qo#Ha4d3COcX+9}hM5!7JIGF>7<~C(Ear^Sn zm^ZFkV6~Ula6+8S?oOROOA6$C&q&dp`>oR-2Ym3(HT@O7Sd5c~+kjrmM)YmgPH*tL zX+znN>`tv;5eOfX?h{AuX^LK~V#gPCu=)Tigtq9&?7Xh$qN|%A$?V*v=&-2F$zTUv z`C#WyIrChS5|Kgm_GeudCFf;)!WH7FI60j^0o#65o6`w*S7R@)88n$1nrgU(oU0M9 zx+EuMkC>(4j1;m6NoGqEkpJYJ?vc|B zOlwT3t&UgL!pX_P*6g36`ZXQ; z9~Cv}ANFnJGp(;ZhS(@FT;3e)0)Kp;h^x;$*xZn*k0U6-&FwI=uOGaODdrsp-!K$Ac32^c{+FhI-HkYd5v=`PGsg%6I`4d9Jy)uW0y%) zm&j^9WBAp*P8#kGJUhB!L?a%h$hJgQrx!6KCB_TRo%9{t0J7KW8!o1B!NC)VGLM5! zpZy5Jc{`r{1e(jd%jsG7k%I+m#CGS*BPA65ZVW~fLYw0dA-H_}O zrkGFL&P1PG9p2(%QiEWm6x;U-U&I#;Em$nx-_I^wtgw3xUPVVu zqSuKnx&dIT-XT+T10p;yjo1Y)z(x1fb8Dzfn8e yu?e%!_ptzGB|8GrCfu%p?(_ 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 GZ~q4|mN%#X literal 59203 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

      K7UpUK$>l@ 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 E2O(~oYXATM diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 442d9132e..df97d72b8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 4f906e0c8..f5feea6d6 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,69 +15,104 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -87,9 +122,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -98,88 +133,120 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=`expr $i + 1` - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index ac1b06f93..9b42019c7 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,8 +13,10 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +27,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,13 +43,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -56,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -75,13 +78,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/repl b/repl index c6014bbb4..e31926a9d 100755 --- a/repl +++ b/repl @@ -1,7 +1,5 @@ #!/usr/bin/env bash -set -e -set -u -set -o pipefail +set -euo pipefail JDWP=false JDWP_PORT=8000 @@ -37,12 +35,13 @@ echo "Compiling and computing classpath (May take a while)" # /smack/smack-repl/build/classes/main:/smack/smack-repl/build/ # resources/main:/smack/smack-tcp/build/libs/smack-tcp-4.2.0-alpha4-SNAPSHOT.jar # So perform a "tail -n1" on the output of gradle -GRADLE_CLASSPATH="$(gradle :smack-repl:printClasspath --quiet |\ +GRADLE_CLASSPATH="$(${GRADLE_BIN:-./gradlew} :smack-repl:printClasspath --quiet |\ tail -n1)" echo "Finished, starting REPL" -java "${EXTRA_JAVA_ARGS[@]}" \ +exec java \ + "${EXTRA_JAVA_ARGS[@]}" \ -Dscala.usejavacp=true \ -classpath "${GRADLE_CLASSPATH}" \ ammonite.Main \ - --predef "smack-repl/scala.repl" + --predef smack-repl/scala.repl diff --git a/resources/releasedocs/README.html b/resources/releasedocs/README.html deleted file mode 100644 index d25eaf624..000000000 --- a/resources/releasedocs/README.html +++ /dev/null @@ -1,221 +0,0 @@ - - - - - Smack Readme - - - - -

      - - - - -
      - -

      - - - - - - - - - -
      version:@version@
      released:@releasedate@
      - -

      -Thank you for downloading Smack! This version of Smack is compatible -with JVMs @targetCompatibility@ or higher. Using a build system which -is able to consume Maven artifacts, like gradle or Maven, is highly -recommended when using Smack. -

      - -

      - This is not the real README. Please visit -

      - https://www.igniterealtime.org/projects/smack/readme -
      - for the README of the current stable Smack version. -

      - -

      - Smack tries to depend on as few as possible libraries. The only - requirement is jXMPP. For DNS - resolution we recommend to - use MiniDNS. -

      - -

      -Start off by viewing the documentation -that can be found in the "documentation" directory included with this distribution. -

      -Further information can be found on the -Smack website. If you need help using or would like to make contributions or -fixes to the code, please visit the -online forum. -

      - -

      Changelog and Upgrading

      - -View the changelog for a list of changes since the -last release. - -

      License Agreements

      -

        -
      • Use of the Smack source code is governed by the Apache License Version 2.0: -
        - Copyright 2002-2008 Jive Software.
        -
        - 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 contains icons and images licensed from INCORS GmbH. You are not licensed -to use these icons outside of Smack.
      • - -
      • Third-party source code is licensed as noted in their source files. - -
      -
      -
      - - diff --git a/settings.gradle b/settings.gradle index 8a7fececc..2ed68cff5 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,7 @@ +pluginManagement { + includeBuild('build-logic') +} + // The name of the root project. // If we would not set the name, then gradle would use the directory // name of the root directory diff --git a/smack-android-extensions/build.gradle b/smack-android-extensions/build.gradle index 0cdad8bda..ce9a40fc4 100644 --- a/smack-android-extensions/build.gradle +++ b/smack-android-extensions/build.gradle @@ -1,3 +1,9 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' + id 'org.igniterealtime.smack.android-conventions' + id 'org.igniterealtime.smack.android-boot-classpath-conventions' +} + description = """\ Extra Smack extensions for Android.""" @@ -8,5 +14,5 @@ dependencies { api project(':smack-extensions') // Add the Android jar to the Eclipse .classpath. - compileClasspath files(androidBootClasspath) + implementation files(androidBootClasspath) } diff --git a/smack-android/build.gradle b/smack-android/build.gradle index 556a526eb..ef158e137 100644 --- a/smack-android/build.gradle +++ b/smack-android/build.gradle @@ -1,3 +1,9 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' + id 'org.igniterealtime.smack.android-conventions' + id 'org.igniterealtime.smack.android-boot-classpath-conventions' +} + description = """\ Smack for Android. All the required dependencies to run Smack on Android. @@ -16,13 +22,13 @@ dependencies { // used in non-Android projects. implementation "org.minidns:minidns-android21:$miniDnsVersion" - // androidProjects lists all projects that are checked to compile against android.jar - // Filter out the optional Smack dependencies from androidProjects - (androidProjects - androidOptionalProjects) - .each { project -> - api project - } + api project(':smack-core') + api project(':smack-im') + api project(':smack-resolver-minidns') + api project(':smack-sasl-provided') + api project(':smack-xmlparser') + api project(':smack-xmlparser-xpp3') // Add the Android jar to the Eclipse .classpath. - compileClasspath files(androidBootClasspath) + implementation files(androidBootClasspath) } diff --git a/smack-bosh/build.gradle b/smack-bosh/build.gradle index fcd3d5896..d939a9e46 100644 --- a/smack-bosh/build.gradle +++ b/smack-bosh/build.gradle @@ -1,3 +1,8 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' + id 'org.igniterealtime.smack.android-conventions' +} + description = """\ Smack BOSH API. This API is considered beta quality.""" diff --git a/smack-core/build.gradle b/smack-core/build.gradle index d29c04d80..1ffb92eb7 100644 --- a/smack-core/build.gradle +++ b/smack-core/build.gradle @@ -1,7 +1,7 @@ -// Note that this is also declared in the main build.gradle for -// subprojects, but since evaluationDependsOnChildren is enabled we -// need to declare it here too to have bundle{bnd{...}} available -apply plugin: 'biz.aQute.bnd.builder' +plugins { + id 'org.igniterealtime.smack.java-common-conventions' + id 'org.igniterealtime.smack.android-conventions' +} description = """\ Smack core components.""" @@ -16,6 +16,9 @@ dependencies { api "org.jxmpp:jxmpp-jid:$jxmppVersion" api "org.minidns:minidns-core:$miniDnsVersion" + // TODO: Migrate Junit4 tests to Junit5. + testImplementation "org.junit.vintage:junit-vintage-engine:$junitVersion" + testFixturesImplementation project(':smack-xmlparser-stax') testFixturesImplementation project(':smack-xmlparser-xpp3') @@ -59,7 +62,7 @@ task createVersionResource(type: CreateFileTask) { outputFile = new File(projectDir, 'src/main/resources/org.jivesoftware.smack/version') } -compileJava.dependsOn(createVersionResource) +processResources.dependsOn(createVersionResource) jar { bundle { 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 8e3e66828..e29ed25f8 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java @@ -1,6 +1,6 @@ /** * - * Copyright 2009 Jive Software, 2018-2022 Florian Schmaus. + * Copyright 2009 Jive Software, 2018-2024 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ package org.jivesoftware.smack; import java.io.IOException; import java.io.Reader; import java.io.Writer; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; @@ -1067,6 +1068,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { } @Override + @SuppressWarnings("TypeParameterUnusedInFormals") public I sendIqRequestAndWaitForResponse(IQ request) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { StanzaCollector collector = createStanzaCollectorAndSend(request); @@ -1214,7 +1216,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { } Stanza packet = (Stanza) sendTopLevelStreamElement; - final List listenersToNotify = new LinkedList<>(); + final List listenersToNotify = new ArrayList<>(); synchronized (sendListeners) { for (ListenerWrapper listenerWrapper : sendListeners.values()) { if (listenerWrapper.filterMatches(packet)) { @@ -1284,7 +1286,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { private static , MP extends MessageOrPresence> MP fireMessageOrPresenceInterceptors( MP messageOrPresence, Map, GenericInterceptorWrapper> interceptors) { - List> interceptorsToInvoke = new LinkedList<>(); + List> interceptorsToInvoke = new ArrayList<>(); synchronized (interceptors) { for (GenericInterceptorWrapper interceptorWrapper : interceptors.values()) { if (interceptorWrapper.filterMatches(messageOrPresence)) { @@ -1319,7 +1321,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { * @return the, potentially modified stanza, after the interceptors are run. */ private Stanza firePacketInterceptors(Stanza packet) { - List interceptorsToInvoke = new LinkedList<>(); + List interceptorsToInvoke = new ArrayList<>(); synchronized (interceptors) { for (InterceptorWrapper interceptorWrapper : interceptors.values()) { if (interceptorWrapper.filterMatches(packet)) { @@ -1604,7 +1606,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { // First handle the async recv listeners. Note that this code is very similar to what follows a few lines below, // the only difference is that asyncRecvListeners is used here and that the packet listeners are started in // their own thread. - final Collection listenersToNotify = new LinkedList<>(); + final Collection listenersToNotify = new ArrayList<>(); extractMatchingListeners(packet, asyncRecvListeners, listenersToNotify); for (final StanzaListener listener : listenersToNotify) { asyncGoLimited(new Runnable() { @@ -1930,7 +1932,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { // Default implementation does nothing } - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"}) @Override public F getFeature(QName qname) { return (F) streamFeatures.get(qname); @@ -2175,6 +2177,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { * {@link #maxAsyncRunnables}. Note that we use a {@code LinkedList} in order to avoid space blowups in case the * list ever becomes very big and shrinks again. */ + @SuppressWarnings("JdkObsolete") private final Queue deferredAsyncRunnables = new LinkedList<>(); private int deferredAsyncRunnablesCount; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/ScheduledAction.java b/smack-core/src/main/java/org/jivesoftware/smack/ScheduledAction.java index da0377fab..def612a19 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/ScheduledAction.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/ScheduledAction.java @@ -1,6 +1,6 @@ /** * - * Copyright 2018 Florian Schmaus + * Copyright 2018-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,11 +50,13 @@ public class ScheduledAction implements Delayed { return smackReactor.cancel(this); } + @SuppressWarnings("JavaUtilDate") public boolean isDue() { Date now = new Date(); return now.after(releaseTime); } + @SuppressWarnings("JavaUtilDate") public long getTimeToDueMillis() { long now = System.currentTimeMillis(); return releaseTime.getTime() - now; 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 efc6ca602..8fc59ab3a 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SmackReactor.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SmackReactor.java @@ -1,6 +1,6 @@ /** * - * Copyright 2018-2023 Florian Schmaus + * Copyright 2018-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -144,6 +144,7 @@ public class SmackReactor { } } + @SuppressWarnings("JavaUtilDate") ScheduledAction schedule(Runnable runnable, long delay, TimeUnit unit, ScheduledAction.Kind scheduledActionKind) { long releaseTimeEpoch = System.currentTimeMillis() + unit.toMillis(delay); Date releaseTimeDate = new Date(releaseTimeEpoch); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/StanzaCollector.java b/smack-core/src/main/java/org/jivesoftware/smack/StanzaCollector.java index 2ceaaf19d..dfa0ec7d2 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/StanzaCollector.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/StanzaCollector.java @@ -1,6 +1,6 @@ /** * - * Copyright 2003-2007 Jive Software, 2016-2019 Florian Schmaus. + * Copyright 2003-2007 Jive Software, 2016-2024 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -117,7 +117,7 @@ public final class StanzaCollector implements AutoCloseable { * @return the next stanza result, or null if there are no more * results. */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"}) public synchronized

      P pollResult() { return (P) resultQueue.poll(); } @@ -134,6 +134,7 @@ public final class StanzaCollector implements AutoCloseable { * @return the next available packet. * @throws XMPPErrorException in case an error response. */ + @SuppressWarnings("TypeParameterUnusedInFormals") public

      P pollResultOrThrow() throws XMPPErrorException { P result = pollResult(); if (result != null) { @@ -150,7 +151,7 @@ public final class StanzaCollector implements AutoCloseable { * @return the next available packet. * @throws InterruptedException if the calling thread was interrupted. */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"}) // TODO: Consider removing this method as it is hardly ever useful. public synchronized

      P nextResultBlockForever() throws InterruptedException { throwIfCancelled(); @@ -175,6 +176,7 @@ public final class StanzaCollector implements AutoCloseable { * @return the next available packet. * @throws InterruptedException if the calling thread was interrupted. */ + @SuppressWarnings("TypeParameterUnusedInFormals") public

      P nextResult() throws InterruptedException { return nextResult(connection.getReplyTimeout()); } @@ -191,7 +193,7 @@ public final class StanzaCollector implements AutoCloseable { * @return the next available stanza or null on timeout or connection error. * @throws InterruptedException if the calling thread was interrupted. */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"}) public

      P nextResult(long timeout) throws InterruptedException { throwIfCancelled(); P res = null; @@ -223,6 +225,7 @@ public final class StanzaCollector implements AutoCloseable { * @throws NotConnectedException if the XMPP connection is not connected. * @see #nextResultOrThrow(long) */ + @SuppressWarnings("TypeParameterUnusedInFormals") public

      P nextResultOrThrow() throws NoResponseException, XMPPErrorException, InterruptedException, NotConnectedException { return nextResultOrThrow(connection.getReplyTimeout()); @@ -263,6 +266,7 @@ public final class StanzaCollector implements AutoCloseable { * @throws InterruptedException if the calling thread was interrupted. * @throws NotConnectedException if there was no response and the connection got disconnected. */ + @SuppressWarnings("TypeParameterUnusedInFormals") public

      P nextResultOrThrow(long timeout) throws NoResponseException, XMPPErrorException, InterruptedException, NotConnectedException { P result; 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 c3bd2d414..45cd8328f 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java @@ -318,6 +318,7 @@ public interface XMPPConnection { * @throws InterruptedException if the calling thread was interrupted. * @since 4.3 */ + @SuppressWarnings("TypeParameterUnusedInFormals") I sendIqRequestAndWaitForResponse(IQ request) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException; @@ -590,6 +591,7 @@ public interface XMPPConnection { * @return a stanza extensions of the feature or null * @since 4.4 */ + @SuppressWarnings("TypeParameterUnusedInFormals") F getFeature(QName qname); /** diff --git a/smack-core/src/main/java/org/jivesoftware/smack/c2s/ModularXmppClientToServerConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/c2s/ModularXmppClientToServerConnection.java index 495720deb..0ece95aa2 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/c2s/ModularXmppClientToServerConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/c2s/ModularXmppClientToServerConnection.java @@ -301,7 +301,7 @@ public final class ModularXmppClientToServerConnection extends AbstractXMPPConne currentStateVertex = StateDescriptorGraph.convertToStateGraph(initialStateDescriptorVertex, connectionInternal); } - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"}) public > CM getConnectionModuleFor( Class descriptorClass) { return (CM) connectionModules.get(descriptorClass); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/compression/zlib/ZlibXmppCompressionFactory.java b/smack-core/src/main/java/org/jivesoftware/smack/compression/zlib/ZlibXmppCompressionFactory.java index 096147931..d851b0c44 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/compression/zlib/ZlibXmppCompressionFactory.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/compression/zlib/ZlibXmppCompressionFactory.java @@ -143,7 +143,9 @@ public final class ZlibXmppCompressionFactory extends XmppCompressionFactory { int bytesWritten = compressor.deflate(buffer, initialOutputBufferPosition, length, flushMode); int newOutputBufferPosition = initialOutputBufferPosition + bytesWritten; - outputBuffer.position(newOutputBufferPosition); + // Workaround for Android API not matching Java >=9 API. + // See https://issuetracker.google.com/issues/369219141 + ((java.nio.Buffer) outputBuffer).position(newOutputBufferPosition); totalBytesWritten += bytesWritten; @@ -156,7 +158,9 @@ public final class ZlibXmppCompressionFactory extends XmppCompressionFactory { increasedBufferSize = MINIMUM_OUTPUT_BUFFER_INCREASE; } ByteBuffer newCurrentOutputBuffer = ByteBuffer.allocate(increasedBufferSize); - outputBuffer.flip(); + // Workaround for Android API not matching Java >=9 API. + // See https://issuetracker.google.com/issues/369219141 + ((java.nio.Buffer) outputBuffer).flip(); newCurrentOutputBuffer.put(outputBuffer); outputBuffer = newCurrentOutputBuffer; } @@ -202,7 +206,9 @@ public final class ZlibXmppCompressionFactory extends XmppCompressionFactory { throw new IOException(e); } - outputBuffer.position(inflateOutputBufferOffset + bytesInflated); + // Workaround for Android API not matching Java >=9 API. + // See https://issuetracker.google.com/issues/369219141 + ((java.nio.Buffer) outputBuffer).position(inflateOutputBufferOffset + bytesInflated); decompressorOutBytes += bytesInflated; @@ -212,7 +218,9 @@ public final class ZlibXmppCompressionFactory extends XmppCompressionFactory { int increasedBufferSize = outputBuffer.capacity() * 2; ByteBuffer increasedOutputBuffer = ByteBuffer.allocate(increasedBufferSize); - outputBuffer.flip(); + // Workaround for Android API not matching Java >=9 API. + // See https://issuetracker.google.com/issues/369219141 + ((java.nio.Buffer) outputBuffer).flip(); increasedOutputBuffer.put(outputBuffer); outputBuffer = increasedOutputBuffer; } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/debugger/ConsoleDebugger.java b/smack-core/src/main/java/org/jivesoftware/smack/debugger/ConsoleDebugger.java index 12d140aad..95c339a5d 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/debugger/ConsoleDebugger.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/debugger/ConsoleDebugger.java @@ -41,6 +41,7 @@ public class ConsoleDebugger extends AbstractDebugger { super(connection); } + @SuppressWarnings("JavaUtilDate") @Override protected void log(String logMessage) { String formatedDate; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/initializer/UrlInitializer.java b/smack-core/src/main/java/org/jivesoftware/smack/initializer/UrlInitializer.java index ec7b047e7..33ced4f39 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/initializer/UrlInitializer.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/initializer/UrlInitializer.java @@ -1,6 +1,6 @@ /** * - * Copyright 2014-2018 Florian Schmaus + * Copyright 2014-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ package org.jivesoftware.smack.initializer; import java.io.InputStream; import java.net.URI; -import java.util.LinkedList; +import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -42,7 +42,7 @@ public abstract class UrlInitializer implements SmackInitializer { public List initialize() { InputStream is = null; final ClassLoader classLoader = this.getClass().getClassLoader(); - final List exceptions = new LinkedList(); + final List exceptions = new ArrayList(); final String providerUriString = getProvidersUri(); if (providerUriString != null) { try { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/AbstractError.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/AbstractError.java index 147b4f031..50067fc14 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/AbstractError.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/AbstractError.java @@ -1,6 +1,6 @@ /** * - * Copyright 2014-2021 Florian Schmaus + * Copyright 2014-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -108,6 +108,7 @@ public class AbstractError { * @param type of the ExtensionElement. * @return the extension, or null if it doesn't exist. */ + @SuppressWarnings("TypeParameterUnusedInFormals") public PE getExtension(String elementName, String namespace) { return PacketUtil.extensionElementFrom(extensions, elementName, namespace); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/Mechanisms.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/Mechanisms.java index a981589ee..2d36eb920 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/Mechanisms.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/Mechanisms.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2014-2020 Florian Schmaus + * Copyright © 2014-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,9 @@ */ package org.jivesoftware.smack.packet; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.LinkedList; import java.util.List; import javax.xml.namespace.QName; @@ -31,7 +31,7 @@ public class Mechanisms implements ExtensionElement { public static final String NAMESPACE = "urn:ietf:params:xml:ns:xmpp-sasl"; public static final QName QNAME = new QName(NAMESPACE, ELEMENT); - public final List mechanisms = new LinkedList(); + public final List mechanisms = new ArrayList(); public Mechanisms(String mechanism) { mechanisms.add(mechanism); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/StandardExtensionElement.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/StandardExtensionElement.java index 8ae1f5a7a..9f1959460 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/StandardExtensionElement.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/StandardExtensionElement.java @@ -1,6 +1,6 @@ /** * - * Copyright 2015-2021 Florian Schmaus. + * Copyright 2015-2024 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,9 +53,7 @@ public final class StandardExtensionElement implements XmlElement { /** * Constructs a new extension element with the given name and namespace and nothing else. - *

      * This is meant to construct extension elements used as simple flags in Stanzas. - *

      * * @param name the name of the extension element. * @param namespace the namespace of the extension element. diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaView.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaView.java index 85c4af1a9..e435d7159 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaView.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaView.java @@ -1,6 +1,6 @@ /** * - * Copyright 2019-2021 Florian Schmaus + * Copyright 2019-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ public interface StanzaView extends XmlLangElement { /** * Returns who the stanza is being sent "to", or null if * the value is not set. The XMPP protocol often makes the "to" - * attribute optional, so it does not always need to be set.

      + * attribute optional, so it does not always need to be set. * * @return who the stanza is being sent to, or null if the * value has not been set. @@ -46,7 +46,7 @@ public interface StanzaView extends XmlLangElement { /** * Returns who the stanza is being sent "from" or null if * the value is not set. The XMPP protocol often makes the "from" - * attribute optional, so it does not always need to be set.

      + * attribute optional, so it does not always need to be set. * * @return who the stanza is being sent from, or null if the * value has not been set. diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderFileLoader.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderFileLoader.java index 11da95318..2781fe0d9 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderFileLoader.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderFileLoader.java @@ -17,9 +17,9 @@ package org.jivesoftware.smack.provider; import java.io.InputStream; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.LinkedList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -39,11 +39,11 @@ import org.jivesoftware.smack.xml.XmlPullParser; public class ProviderFileLoader implements ProviderLoader { private static final Logger LOGGER = Logger.getLogger(ProviderFileLoader.class.getName()); - private final Collection iqProviders = new LinkedList(); - private final Collection extProviders = new LinkedList(); - private final Collection sfProviders = new LinkedList(); + private final Collection iqProviders = new ArrayList(); + private final Collection extProviders = new ArrayList(); + private final Collection sfProviders = new ArrayList(); - private List exceptions = new LinkedList(); + private List exceptions = new ArrayList(); public ProviderFileLoader(InputStream providerStream) { this(providerStream, ProviderFileLoader.class.getClassLoader()); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderManager.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderManager.java index 0943f31d6..b2f08cc3a 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderManager.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderManager.java @@ -97,6 +97,7 @@ import org.jivesoftware.smack.util.XmppElementUtil; * </extensionProvider> * </smackProviders> * + *

      * If multiple provider entries attempt to register to handle the same element name and namespace, * the first entry loaded from the classpath will take precedence. Whenever a stanza extension * is found in a packet, parsing will be passed to the correct provider. Each provider @@ -106,7 +107,8 @@ import org.jivesoftware.smack.util.XmppElementUtil; * set the properties of th class using the values in the stanza extension sub-element. When an * extension provider is not registered for an element name and namespace combination, Smack will * store all top-level elements of the sub-packet in DefaultPacketExtension object and then - * attach it to the packet.

      + * attach it to the packet. + *

      * * @author Matt Tucker */ diff --git a/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/ScramMechanism.java b/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/ScramMechanism.java index 8f4133c81..6dc482ce3 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/ScramMechanism.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/ScramMechanism.java @@ -271,6 +271,7 @@ public abstract class ScramMechanism extends SASLMechanism { return null; } + @SuppressWarnings("MixedMutabilityReturnType") private static Map parseAttributes(String string) throws SmackSaslException { if (string.length() == 0) { return Collections.emptyMap(); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/MultiMap.java b/smack-core/src/main/java/org/jivesoftware/smack/util/MultiMap.java index 852e01bf7..7e9889e57 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/MultiMap.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/MultiMap.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2015-2021 Florian Schmaus + * Copyright © 2015-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -184,13 +184,14 @@ public class MultiMap { } /** - * Remove the given number of values for a given key. May return less values then requested. + * Remove the given number of values for a given key. May return less values than requested. * * @param key the key to remove from. * @param num the number of values to remove. * @return a list of the removed values. * @since 4.4.0 */ + @SuppressWarnings("MixedMutabilityReturnType") public List remove(K key, int num) { List values = map.get(key); if (values == null) { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java index c04514075..69f0aaca2 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java @@ -1,6 +1,6 @@ /** * - * Copyright 2003-2007 Jive Software, 2019-2023 Florian Schmaus. + * Copyright 2003-2007 Jive Software, 2019-2024 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,6 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.logging.Level; @@ -87,7 +86,7 @@ public class PacketParserUtils { return parser; } - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"}) public static S parseStanza(String stanza) throws XmlPullParserException, SmackParsingException, IOException { return (S) parseStanza(getParserFor(stanza), XmlEnvironment.EMPTY); } @@ -644,7 +643,7 @@ public class PacketParserUtils { assert parser.getEventType() == XmlPullParser.Event.START_ELEMENT; String name; final int initialDepth = parser.getDepth(); - List methods = new LinkedList<>(); + List methods = new ArrayList<>(); outerloop: while (true) { XmlPullParser.Event eventType = parser.next(); switch (eventType) { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/PacketUtil.java b/smack-core/src/main/java/org/jivesoftware/smack/util/PacketUtil.java index a68e91dd0..40da6f4d6 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/PacketUtil.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/PacketUtil.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2014-2021 Florian Schmaus + * Copyright © 2014-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +32,7 @@ public class PacketUtil { * * @return the extension element */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"}) public static PE extensionElementFrom(Collection collection, String element, String namespace) { for (XmlElement packetExtension : collection) { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/Pair.java b/smack-core/src/main/java/org/jivesoftware/smack/util/Pair.java index 08bf41234..76ebc1dc5 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/Pair.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/Pair.java @@ -1,6 +1,6 @@ /** * - * Copyright 2020 Florian Schmaus. + * Copyright 2020-2024 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,7 @@ public final class Pair { return new Pair<>(first, second); } + @SuppressWarnings("ReturnValueIgnored") public static Pair createAndInitHashCode(F first, S second) { Pair pair = new Pair<>(first, second); pair.hashCode(); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java index 1a66cc0f3..ffadbda00 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java @@ -329,7 +329,10 @@ public class StringUtils { throw new AssertionError(e); } - return charBuffer.flip().toString(); + // Workaround for Android API not matching Java >=9 API. + // See https://issuetracker.google.com/issues/369219141 + ((java.nio.Buffer) charBuffer).flip(); + return charBuffer.toString(); } private static void randomString(Appendable appendable, Random random, char[] alphabet, int numRandomChars) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/XmppElementUtil.java b/smack-core/src/main/java/org/jivesoftware/smack/util/XmppElementUtil.java index 5639a7e5f..7ffe2f2eb 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/XmppElementUtil.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/XmppElementUtil.java @@ -71,6 +71,7 @@ public class XmppElementUtil { return qname; } + @SuppressWarnings("MixedMutabilityReturnType") public static List getElementsFrom( MultiMap elementMap, Class extensionElementClass) { QName qname = XmppElementUtil.getQNameFor(extensionElementClass); diff --git a/smack-core/src/testFixtures/java/org/jivesoftware/smack/DummyConnection.java b/smack-core/src/testFixtures/java/org/jivesoftware/smack/DummyConnection.java index 7df852975..2faca2ebc 100644 --- a/smack-core/src/testFixtures/java/org/jivesoftware/smack/DummyConnection.java +++ b/smack-core/src/testFixtures/java/org/jivesoftware/smack/DummyConnection.java @@ -91,6 +91,7 @@ public class DummyConnection extends AbstractXMPPConnection { user = getUserJid(); } + @SuppressWarnings("JavaUtilDate") @Override protected void connectInternal() { connected = true; @@ -162,6 +163,7 @@ public class DummyConnection extends AbstractXMPPConnection { * @param

      the top level stream element class. * @return a sent packet. */ + @SuppressWarnings("TypeParameterUnusedInFormals") public

      P getSentPacket() { return getSentPacket(5 * 60); } @@ -176,7 +178,7 @@ public class DummyConnection extends AbstractXMPPConnection { * @param

      the top level stream element class. * @return a sent packet. */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"}) public

      P getSentPacket(int wait) { try { return (P) queue.poll(wait, TimeUnit.SECONDS); diff --git a/smack-debug-slf4j/build.gradle b/smack-debug-slf4j/build.gradle index 35d904a7e..71eae05b4 100644 --- a/smack-debug-slf4j/build.gradle +++ b/smack-debug-slf4j/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' +} + description = """\ Smack slf4j debugger. Inspect the exchanged XMPP stanzas. diff --git a/smack-debug/build.gradle b/smack-debug/build.gradle index 959caff4f..7c9fdc0f1 100644 --- a/smack-debug/build.gradle +++ b/smack-debug/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' +} + description = """\ Smack GUI debugger. Inspect the exchanged XMPP stanzas.""" diff --git a/smack-debug/src/main/java/org/jivesoftware/smackx/debugger/EnhancedDebugger.java b/smack-debug/src/main/java/org/jivesoftware/smackx/debugger/EnhancedDebugger.java index 40d2e5263..23eba68ec 100644 --- a/smack-debug/src/main/java/org/jivesoftware/smackx/debugger/EnhancedDebugger.java +++ b/smack-debug/src/main/java/org/jivesoftware/smackx/debugger/EnhancedDebugger.java @@ -160,6 +160,7 @@ public class EnhancedDebugger extends SmackDebugger { private ReaderListener readerListener; private WriterListener writerListener; + @SuppressWarnings("JavaUtilDate") private Date creationTime = new Date(); // Statistics variables @@ -756,6 +757,7 @@ public class EnhancedDebugger extends SmackDebugger { * @param dateFormatter the SimpleDateFormat to use to format Dates * @param packet the read stanza to add to the table */ + @SuppressWarnings("JavaUtilDate") private void addReadPacketToTable(final SimpleDateFormat dateFormatter, final TopLevelStreamElement packet) { SwingUtilities.invokeLater(new Runnable() { @Override @@ -827,6 +829,7 @@ public class EnhancedDebugger extends SmackDebugger { * @param dateFormatter the SimpleDateFormat to use to format Dates * @param packet the sent stanza to add to the table */ + @SuppressWarnings("JavaUtilDate") private void addSentPacketToTable(final SimpleDateFormat dateFormatter, final TopLevelStreamElement packet) { SwingUtilities.invokeLater(new Runnable() { @Override diff --git a/smack-debug/src/main/java/org/jivesoftware/smackx/debugger/EnhancedDebuggerWindow.java b/smack-debug/src/main/java/org/jivesoftware/smackx/debugger/EnhancedDebuggerWindow.java index 5755207d8..cadcb0b53 100644 --- a/smack-debug/src/main/java/org/jivesoftware/smackx/debugger/EnhancedDebuggerWindow.java +++ b/smack-debug/src/main/java/org/jivesoftware/smackx/debugger/EnhancedDebuggerWindow.java @@ -204,7 +204,7 @@ public final class EnhancedDebuggerWindow { * Creates the main debug window that provides information about Smack and also shows * a tab panel for each connection that is being debugged. */ - @SuppressWarnings({ "rawtypes", "unchecked" }) + @SuppressWarnings({ "rawtypes", "unchecked", "JdkObsolete" }) private void createDebug() { frame = new JFrame("Smack Debug Window"); diff --git a/smack-examples/build.gradle b/smack-examples/build.gradle index 7592441a5..244040dd7 100644 --- a/smack-examples/build.gradle +++ b/smack-examples/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' +} + description = """\ Examples and test applications for Smack""" diff --git a/smack-examples/src/main/java/org/igniterealtime/smack/examples/XmppTools.java b/smack-examples/src/main/java/org/igniterealtime/smack/examples/XmppTools.java index f262102c2..70bb9f1f2 100644 --- a/smack-examples/src/main/java/org/igniterealtime/smack/examples/XmppTools.java +++ b/smack-examples/src/main/java/org/igniterealtime/smack/examples/XmppTools.java @@ -1,6 +1,6 @@ /** * - * Copyright 2016-2021 Florian Schmaus + * Copyright 2016-2024 Florian Schmaus * * This file is part of smack-examples. * @@ -136,6 +136,7 @@ public class XmppTools { // CHECKSTYLE:ON } + @SuppressWarnings("JavaUtilDate") public static void sendItsAlive(String to, XMPPConnection connection) throws XmppStringprepException, NotConnectedException, InterruptedException { if (to == null) { diff --git a/smack-experimental/build.gradle b/smack-experimental/build.gradle index 9e945e0d5..7484d56f8 100644 --- a/smack-experimental/build.gradle +++ b/smack-experimental/build.gradle @@ -1,3 +1,8 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' + id 'org.igniterealtime.smack.android-conventions' +} + description = """\ Smack experimental extensions. Classes and methods for XEPs that are in status 'experimental' or that should diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/element/IoTFieldsExtension.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/element/IoTFieldsExtension.java index cb280745f..721b1b657 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/element/IoTFieldsExtension.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/element/IoTFieldsExtension.java @@ -83,6 +83,7 @@ public class IoTFieldsExtension implements ExtensionElement { return xml; } + @SuppressWarnings("JavaUtilDate") public static IoTFieldsExtension buildFor(int seqNr, boolean done, NodeInfo nodeInfo, List data) { TimestampElement timestampElement = new TimestampElement(new Date(), data); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/JingleFileTransferChild.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/JingleFileTransferChild.java index b4e9021ec..cab86e550 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/JingleFileTransferChild.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/JingleFileTransferChild.java @@ -1,6 +1,6 @@ /** * - * Copyright 2017 Paul Schaub, 2019 Florian Schmaus + * Copyright 2017 Paul Schaub, 2019-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -167,6 +167,7 @@ public class JingleFileTransferChild implements JingleContentDescriptionChildEle return new JingleFileTransferChild(date, desc, hash, mediaType, name, size, range); } + @SuppressWarnings("JavaUtilDate") public Builder setFile(File file) { return setDate(new Date(file.lastModified())) .setName(file.getAbsolutePath().substring(file.getAbsolutePath().lastIndexOf("/") + 1)) diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/mam/MamManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/mam/MamManager.java index 985ca8b48..6ce58bdea 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/mam/MamManager.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/mam/MamManager.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2017-2023 Florian Schmaus, 2016-2017 Fernando Ramirez + * Copyright © 2017-2024 Florian Schmaus, 2016-2017 Fernando Ramirez * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -387,6 +387,7 @@ public final class MamManager extends Manager { return this; } + @SuppressWarnings("JavaUtilDate") public Builder limitResultsSince(Date start) { if (start == null) { return this; @@ -415,6 +416,7 @@ public final class MamManager extends Manager { return this; } + @SuppressWarnings("JavaUtilDate") public Builder limitResultsBefore(Date end) { if (end == null) { return this; diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/spoiler/element/SpoilerElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/spoiler/element/SpoilerElement.java index 6d5c02fd6..b18a5af5c 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/spoiler/element/SpoilerElement.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/spoiler/element/SpoilerElement.java @@ -114,6 +114,7 @@ public class SpoilerElement implements ExtensionElement { * @param message message * @return map of spoilers */ + @SuppressWarnings("MixedMutabilityReturnType") public static Map getSpoilers(Message message) { if (!containsSpoiler(message)) { return Collections.emptyMap(); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/stanza_content_encryption/element/TimestampAffixElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/stanza_content_encryption/element/TimestampAffixElement.java index 0c48f7b7a..eee726085 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/stanza_content_encryption/element/TimestampAffixElement.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/stanza_content_encryption/element/TimestampAffixElement.java @@ -56,6 +56,7 @@ public class TimestampAffixElement implements NamedElement, AffixElement { return EqualsUtil.equals(this, obj, (e, o) -> e.append(getTimestamp(), o.getTimestamp())); } + @SuppressWarnings("JavaUtilDate") @Override public int hashCode() { return timestamp.hashCode(); diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/mam/FiltersTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/mam/FiltersTest.java index b5c974dce..df14ea279 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/mam/FiltersTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/mam/FiltersTest.java @@ -1,6 +1,6 @@ /** * - * Copyright 2016 Fernando Ramirez, 2018-2020 Florian Schmaus + * Copyright 2016 Fernando Ramirez, 2018-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,6 +46,7 @@ public class FiltersTest extends MamTest { return xml; } + @SuppressWarnings("JavaUtilDate") @Test public void checkStartDateFilter() throws Exception { Date date = new Date(); @@ -61,6 +62,7 @@ public class FiltersTest extends MamTest { assertEquals(getMamXMemberWith(fields, values), dataForm.toXML().toString()); } + @SuppressWarnings("JavaUtilDate") @Test public void checkEndDateFilter() throws Exception { Date date = new Date(); diff --git a/smack-extensions/build.gradle b/smack-extensions/build.gradle index 2489c9f87..0b62da32c 100644 --- a/smack-extensions/build.gradle +++ b/smack-extensions/build.gradle @@ -1,3 +1,8 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' + id 'org.igniterealtime.smack.android-conventions' +} + description = """\ Smack extensions. Classes and methods that implement support for the various XMPP XEPs diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java index 823df54e1..e527d416a 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java @@ -16,8 +16,8 @@ */ package org.jivesoftware.smackx.bytestreams.ibb; +import java.util.ArrayList; import java.util.Collections; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.WeakHashMap; @@ -135,7 +135,7 @@ public final class InBandBytestreamManager extends Manager implements Bytestream * list of listeners that respond to all In-Band Bytestream requests if there are no user * specific listeners for that request */ - private final List allRequestListeners = Collections.synchronizedList(new LinkedList()); + private final List allRequestListeners = Collections.synchronizedList(new ArrayList()); /* listener that handles all incoming In-Band Bytestream requests */ private final InitiationListener initiationListener; @@ -162,7 +162,7 @@ public final class InBandBytestreamManager extends Manager implements Bytestream * list containing session IDs of In-Band Bytestream open packets that should be ignored by the * InitiationListener */ - private final List ignoredBytestreamRequests = Collections.synchronizedList(new LinkedList()); + private final List ignoredBytestreamRequests = Collections.synchronizedList(new ArrayList()); /** * Returns the InBandBytestreamManager to handle In-Band Bytestreams for a given diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java index a0dd45581..fac036a1d 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java @@ -22,7 +22,6 @@ import java.net.Socket; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; @@ -128,7 +127,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream * list of listeners that respond to all bytestream requests if there are not user specific * listeners for that request */ - private final List allRequestListeners = Collections.synchronizedList(new LinkedList()); + private final List allRequestListeners = Collections.synchronizedList(new ArrayList()); /* listener that handles all incoming bytestream requests */ private final InitiationListener initiationListener; @@ -154,7 +153,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream * list containing session IDs of SOCKS5 Bytestream initialization packets that should be * ignored by the InitiationListener */ - private final List ignoredBytestreamRequests = Collections.synchronizedList(new LinkedList()); + private final List ignoredBytestreamRequests = Collections.synchronizedList(new ArrayList()); /** * Returns the Socks5BytestreamManager to handle SOCKS5 Bytestreams for a given diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java index 88e7abfe2..9d1191b3e 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java @@ -26,12 +26,12 @@ import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.LinkedHashSet; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; @@ -107,7 +107,7 @@ public class Socks5Proxy { private final Map connectionMap = new ConcurrentHashMap<>(); /* list of digests connections should be stored */ - private final List allowedConnections = Collections.synchronizedList(new LinkedList()); + private final List allowedConnections = Collections.synchronizedList(new ArrayList()); private final Set localAddresses = new LinkedHashSet<>(4); @@ -345,7 +345,7 @@ public class Socks5Proxy { */ public List getLocalAddresses() { synchronized (localAddresses) { - return new LinkedList<>(localAddresses); + return new ArrayList<>(localAddresses); } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java index c15cdf131..aaa87e2b0 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2009 Jonas Ådahl, 2011-2022 Florian Schmaus + * Copyright © 2009 Jonas Ådahl, 2011-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,12 +19,12 @@ package org.jivesoftware.smackx.caps; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; @@ -555,7 +555,7 @@ public final class EntityCapsManager extends Manager { if (connection != null) JID_TO_NODEVER_CACHE.put(connection.getUser(), new NodeVerHash(entityNode, currentCapsVersion)); - final List identities = new LinkedList<>(ServiceDiscoveryManager.getInstanceFor(connection).getIdentities()); + final List identities = new ArrayList<>(ServiceDiscoveryManager.getInstanceFor(connection).getIdentities()); sdm.setNodeInformationProvider(localNodeVer, new AbstractNodeInformationProvider() { List features = sdm.getFeatures(); List packetExtensions = sdm.getExtendedInfo(); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java index 3953b9c63..e50f6d956 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java @@ -22,7 +22,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; @@ -772,7 +771,7 @@ public final class ServiceDiscoveryManager extends Manager { return serviceDiscoInfo; } } - serviceDiscoInfo = new LinkedList<>(); + serviceDiscoInfo = new ArrayList<>(); // Send the disco packet to the server itself DiscoverInfo info; try { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java index 08560bc25..9df5c64ac 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java @@ -19,7 +19,6 @@ package org.jivesoftware.smackx.disco.packet; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; -import java.util.LinkedList; import java.util.List; import java.util.Set; @@ -184,7 +183,7 @@ public class DiscoverInfo extends IQ implements DiscoverInfoView { * @return true if duplicate identities where found, otherwise false */ public boolean containsDuplicateIdentities() { - List checkedIdentities = new LinkedList<>(); + List checkedIdentities = new ArrayList<>(identities.size()); for (Identity i : identities) { for (Identity i2 : checkedIdentities) { if (i.equals(i2)) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverItems.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverItems.java index 34c62a8a1..a6394716c 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverItems.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverItems.java @@ -16,9 +16,9 @@ */ package org.jivesoftware.smackx.disco.packet; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.LinkedList; import java.util.List; import org.jivesoftware.smack.packet.IQ; @@ -40,7 +40,7 @@ public class DiscoverItems extends IQ { public static final String ELEMENT = QUERY_ELEMENT; public static final String NAMESPACE = "http://jabber.org/protocol/disco#items"; - private final List items = new LinkedList<>(); + private final List items = new ArrayList<>(); private String node; public DiscoverItems() { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/provider/RegistrationProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/provider/RegistrationProvider.java index 67da11bbe..d087a5bf4 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/provider/RegistrationProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/provider/RegistrationProvider.java @@ -17,8 +17,8 @@ package org.jivesoftware.smackx.iqregister.provider; import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -40,7 +40,7 @@ public class RegistrationProvider extends IqProvider { public Registration parse(XmlPullParser parser, int initialDepth, IqData iqData, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException { String instruction = null; Map fields = new HashMap<>(); - List packetExtensions = new LinkedList<>(); + List packetExtensions = new ArrayList<>(); outerloop: while (true) { XmlPullParser.Event eventType = parser.next(); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqversion/packet/Version.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqversion/packet/Version.java index b0dd5c1d0..fb0ca01fa 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqversion/packet/Version.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqversion/packet/Version.java @@ -1,6 +1,6 @@ /** * - * Copyright 2003-2007 Jive Software, 2021 Florian Schmaus. + * Copyright 2003-2007 Jive Software, 2021-2024 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,7 @@ import org.jivesoftware.smack.util.StringUtils; /** * A Version IQ packet, which is used by XMPP clients to discover version information - * about the software running at another entity's JID.

      + * about the software running at another entity's JID. * * @author Gaston Dombiak */ diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/last_interaction/element/IdleElement.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/last_interaction/element/IdleElement.java index 2799c1224..6603fe21b 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/last_interaction/element/IdleElement.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/last_interaction/element/IdleElement.java @@ -37,6 +37,7 @@ public class IdleElement implements ExtensionElement { /** * Create a new IdleElement with the current date as date of last user interaction. */ + @SuppressWarnings("JavaUtilDate") public IdleElement() { this(new Date()); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucEnterConfiguration.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucEnterConfiguration.java index e2a73dad1..58c0c4e26 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucEnterConfiguration.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucEnterConfiguration.java @@ -101,9 +101,7 @@ public final class MucEnterConfiguration { /** * Set the presence used to join the MUC room. - *

      * The consumer must not modify the presence type, otherwise an {@link IllegalArgumentException} will be thrown. - *

      * * @param presenceBuilderConsumer a consumer which will be passed the presence build. * @return a reference to this builder. diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java index 3c283adc5..e71f6b523 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java @@ -1842,7 +1842,7 @@ public class MultiUserChat { /** * Returns the presence info for a particular user, or null if the user - * is not in the room.

      + * is not in the room. * * @param user the room occupant to search for his presence. The format of user must * be: roomName@service/nickname (e.g. darkcave@macbeth.shakespeare.lit/thirdwitch). @@ -1856,7 +1856,7 @@ public class MultiUserChat { /** * Returns the Occupant information for a particular occupant, or null if the * user is not in the room. The Occupant object may include information such as full - * JID of the user as well as the role and affiliation of the user in the room.

      + * JID of the user as well as the role and affiliation of the user in the room. * * @param user the room occupant to search for his presence. The format of user must * be: roomName@service/nickname (e.g. darkcave@macbeth.shakespeare.lit/thirdwitch). diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java index 7ebfdfdc9..4d8c5c637 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java @@ -108,6 +108,7 @@ public final class MultiUserChatManager extends Manager { final WeakReference weakRefConnection = new WeakReference(connection); ServiceDiscoveryManager.getInstanceFor(connection).setNodeInformationProvider(DISCO_NODE, new AbstractNodeInformationProvider() { + @SuppressWarnings({"JavaUtilDate", "MixedMutabilityReturnType"}) @Override public List getNodeItems() { XMPPConnection connection = weakRefConnection.get(); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/ItemPublishEvent.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/ItemPublishEvent.java index 577dad4f7..7018b5934 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/ItemPublishEvent.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/ItemPublishEvent.java @@ -109,6 +109,7 @@ public class ItemPublishEvent extends SubscriptionEvent { return originalDate; } + @SuppressWarnings("JavaUtilDate") @Override public String toString() { return getClass().getName() + " [subscriptions: " + getSubscriptions() + "], [Delayed: " + diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/packet/PubSub.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/packet/PubSub.java index a2756d5ff..cf708afe9 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/packet/PubSub.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/packet/PubSub.java @@ -49,7 +49,7 @@ public class PubSub extends IQ { setType(type); } - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"}) public PE getExtension(PubSubElementType elem) { return (PE) getExtensionElement(elem.getElementName(), elem.getNamespace().getXmlns()); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/rsm/RSMManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/rsm/RSMManager.java index ea6924fae..9f03c257a 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/rsm/RSMManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/rsm/RSMManager.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2014-2021 Florian Schmaus + * Copyright © 2014-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,8 @@ */ package org.jivesoftware.smackx.rsm; +import java.util.ArrayList; import java.util.Collection; -import java.util.LinkedList; import java.util.List; import org.jivesoftware.smack.packet.XmlElement; @@ -29,7 +29,7 @@ import org.jivesoftware.smackx.rsm.packet.RSMSet.PageDirection; public class RSMManager { Collection page(int max) { - List packetExtensions = new LinkedList<>(); + List packetExtensions = new ArrayList<>(); packetExtensions.add(new RSMSet(max)); return packetExtensions; } @@ -45,7 +45,7 @@ public class RSMManager { throw new IllegalArgumentException("returnedExtensions must no be null"); } if (additionalExtensions == null) { - additionalExtensions = new LinkedList<>(); + additionalExtensions = new ArrayList<>(); } RSMSet resultRsmSet = PacketUtil.extensionElementFrom(returnedExtensions, RSMSet.ELEMENT, RSMSet.NAMESPACE); if (resultRsmSet == null) { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/si/provider/StreamInitiationProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/si/provider/StreamInitiationProvider.java index a4be338b5..d6333ed80 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/si/provider/StreamInitiationProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/si/provider/StreamInitiationProvider.java @@ -45,6 +45,7 @@ import org.jxmpp.util.XmppDateTime; public class StreamInitiationProvider extends IqProvider { private static final Logger LOGGER = Logger.getLogger(StreamInitiationProvider.class.getName()); + @SuppressWarnings("JavaUtilDate") @Override public StreamInitiation parse(XmlPullParser parser, int initialDepth, IqData iqData, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException { // si diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/caps/EntityCapsManagerTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/caps/EntityCapsManagerTest.java index 94f0fdaaa..d9a0666c3 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/caps/EntityCapsManagerTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/caps/EntityCapsManagerTest.java @@ -22,8 +22,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.Collection; -import java.util.LinkedList; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.test.util.SmackTestSuite; @@ -218,7 +218,7 @@ public class EntityCapsManagerTest extends SmackTestSuite { di.to(JidCreate.from("juliet@capulet.lit/chamber")); di.ofType(IQ.Type.result); - Collection identities = new LinkedList(); + Collection identities = new ArrayList(); DiscoverInfo.Identity i = new DiscoverInfo.Identity("client", "pc", "Psi 0.11", "en"); identities.add(i); i = new DiscoverInfo.Identity("client", "pc", "Ψ 0.11", "el"); @@ -241,7 +241,7 @@ public class EntityCapsManagerTest extends SmackTestSuite { di.to(")juliet@capulet.lit/chamber"); di.ofType(IQ.Type.result); - Collection identities = new LinkedList(); + Collection identities = new ArrayList(); DiscoverInfo.Identity i = new DiscoverInfo.Identity("client", "pc", "Psi 0.11", "en"); identities.add(i); i = new DiscoverInfo.Identity("client", "pc", "Ψ 0.11", "el"); diff --git a/smack-extensions/src/testFixtures/java/org/jivesoftware/util/Protocol.java b/smack-extensions/src/testFixtures/java/org/jivesoftware/util/Protocol.java index f256a9728..9e1bdc652 100644 --- a/smack-extensions/src/testFixtures/java/org/jivesoftware/util/Protocol.java +++ b/smack-extensions/src/testFixtures/java/org/jivesoftware/util/Protocol.java @@ -89,6 +89,7 @@ public class Protocol { public boolean printProtocol = false; // responses to requests are taken form this queue + @SuppressWarnings("JdkObsolete") private final Queue responses = new LinkedList<>(); // list of verifications diff --git a/smack-im/build.gradle b/smack-im/build.gradle index f3cb2d475..beb30a966 100644 --- a/smack-im/build.gradle +++ b/smack-im/build.gradle @@ -1,3 +1,8 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' + id 'org.igniterealtime.smack.android-conventions' +} + description = """\ Smack IM. Classes and methods for XMPP-IM (RFC 6121): @@ -8,4 +13,7 @@ Roster, Chat and other functionality.""" dependencies { api project(':smack-core') testImplementation(testFixtures(project(":smack-core"))) + + // TODO: Migrate Junit4 tests to Junit5. + testImplementation "org.junit.vintage:junit-vintage-engine:$junitVersion" } diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterUtil.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterUtil.java index 843b24bad..5f2093404 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterUtil.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterUtil.java @@ -1,6 +1,6 @@ /** * - * Copyright 2016 Florian Schmaus + * Copyright 2016-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,6 +34,7 @@ import org.jxmpp.jid.Jid; public class RosterUtil { + @SuppressWarnings("JavaUtilDate") public static void waitUntilOtherEntityIsSubscribed(Roster roster, BareJid otherEntity, long timeoutMillis) throws InterruptedException, TimeoutException { Date deadline = new Date(System.currentTimeMillis() + timeoutMillis); @@ -147,6 +148,7 @@ public class RosterUtil { ensureSubscribedTo(connectionTwo, connectionOne, timeout); } + @SuppressWarnings("JavaUtilDate") public static void ensureSubscribedTo(XMPPConnection connectionOne, XMPPConnection connectionTwo, long timeout) throws NotLoggedInException, NotConnectedException, InterruptedException, TimeoutException { Date deadline = new Date(System.currentTimeMillis() + timeout); diff --git a/smack-integration-test/build.gradle b/smack-integration-test/build.gradle index ea08655af..479ee0036 100644 --- a/smack-integration-test/build.gradle +++ b/smack-integration-test/build.gradle @@ -1,10 +1,15 @@ -apply plugin: 'application' +plugins { + id 'org.igniterealtime.smack.java-common-conventions' + id 'org.igniterealtime.smack.application-conventions' +} description = """\ Smack integration tests.""" -mainClassName = 'org.igniterealtime.smack.inttest.SmackIntegrationTestFramework' -applicationDefaultJvmArgs = ["-enableassertions"] + +application { + mainClass = 'org.igniterealtime.smack.inttest.SmackIntegrationTestFramework' +} dependencies { api project(':smack-java8-full') @@ -20,8 +25,3 @@ dependencies { testFixturesApi(testFixtures(project(":smack-core"))) testImplementation "org.jxmpp:jxmpp-jid:$jxmppVersion:tests" } - -run { - // Pass all system properties down to the "application" run - systemProperties System.getProperties() -} diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java index 0616da38a..889f9bb9c 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java @@ -1,6 +1,6 @@ /** * - * Copyright 2015-2023 Florian Schmaus + * Copyright 2015-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,11 +22,11 @@ import java.io.IOException; import java.lang.reflect.Method; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; @@ -587,7 +587,7 @@ public final class Configuration { } private static File findPropertiesFile() { - List possibleLocations = new LinkedList<>(); + List possibleLocations = new ArrayList<>(); possibleLocations.add("properties"); String userHome = System.getProperty("user.home"); if (userHome != null) { diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java index dd0f7fcac..3fb4edaae 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java @@ -1,6 +1,6 @@ /** * - * Copyright 2015-2023 Florian Schmaus + * Copyright 2015-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,7 +39,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; @@ -698,9 +697,9 @@ public class SmackIntegrationTestFramework { */ public final String testRunId = StringUtils.insecureRandomString(5).toLowerCase(Locale.US); - private final List successfulIntegrationTests = Collections.synchronizedList(new LinkedList()); - private final List failedIntegrationTests = Collections.synchronizedList(new LinkedList()); - private final List impossibleIntegrationTests = Collections.synchronizedList(new LinkedList()); + private final List successfulIntegrationTests = Collections.synchronizedList(new ArrayList()); + private final List failedIntegrationTests = Collections.synchronizedList(new ArrayList()); + private final List impossibleIntegrationTests = Collections.synchronizedList(new ArrayList()); // TODO: Ideally three would only be a list of disabledTests, but since we do not process a disabled test class // any further, we can not determine the concrete disabled tests. diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/ChatTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/ChatTest.java index d956c92ee..56a5ec10e 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/ChatTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/ChatTest.java @@ -66,8 +66,8 @@ public class ChatTest extends AbstractSmackIntegrationTest { JivePropertiesManager.setJavaObjectEnabled(false); } - @SuppressWarnings("deprecation") @SmackIntegrationTest + @SuppressWarnings({"deprecation", "JavaUtilDate"}) public void testProperties() throws Exception { org.jivesoftware.smack.chat.Chat newChat = chatManagerOne.createChat(conTwo.getUser()); StanzaCollector collector = conTwo.createStanzaCollector(new ThreadFilter(newChat.getThreadID())); diff --git a/smack-java8-full/build.gradle b/smack-java8-full/build.gradle index 7607d3c02..61a4e00e0 100644 --- a/smack-java8-full/build.gradle +++ b/smack-java8-full/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' +} + description = """\ Full Smack library for Java SE.""" @@ -44,6 +48,7 @@ task convertModularXmppClientToServerConnectionStateGraphDotToPng(type: Exec) { executable 'dot' args "-Tpng", "-o", "${outputs.files.first()}", "${inputs.files.first()}" } +copyJavadocDocFiles.dependsOn convertModularXmppClientToServerConnectionStateGraphDotToPng task cleanGenerateFiles(type: Delete) { delete 'src/javadoc/org/jivesoftware/smack/full/doc-files/ModularXmppClientToServerConnectionStateGraph.dot', 'src/javadoc/org/jivesoftware/smack/full/doc-files/ModularXmppClientToServerConnectionStateGraph.png' diff --git a/smack-java8/build.gradle b/smack-java8/build.gradle index d26aa5ce3..d3d157ad1 100644 --- a/smack-java8/build.gradle +++ b/smack-java8/build.gradle @@ -1,7 +1,11 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' +} + description = """\ -Smack for Java7 (or higher). +Smack for Java 11 (or higher). This is a pseudo-artifact that pulls all the required dependencies to -run Smack on Java 7 (or higher) JVMs. Usually you want to add additional +run Smack on Java 11 (or higher) JVMs. Usually you want to add additional dependencies to smack-tcp, smack-extensions and smack-experimental.""" dependencies { diff --git a/smack-java8/src/main/java/org/jivesoftware/smack/java7/XmppHostnameVerifier.java b/smack-java8/src/main/java/org/jivesoftware/smack/java7/XmppHostnameVerifier.java index 16e1c5668..a03cd097a 100644 --- a/smack-java8/src/main/java/org/jivesoftware/smack/java7/XmppHostnameVerifier.java +++ b/smack-java8/src/main/java/org/jivesoftware/smack/java7/XmppHostnameVerifier.java @@ -1,6 +1,6 @@ /** * - * Copyright 2015 Florian Schmaus + * Copyright 2015-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,8 +23,8 @@ import java.security.Principal; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; +import java.util.ArrayList; import java.util.Collection; -import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.logging.Level; @@ -135,7 +135,7 @@ public class XmppHostnameVerifier implements HostnameVerifier { private static void matchDns(String name, X509Certificate cert) throws CertificateException { Collection> subjAltNames = cert.getSubjectAlternativeNames(); if (subjAltNames != null) { - List nonMatchingDnsAltnames = new LinkedList<>(); + List nonMatchingDnsAltnames = new ArrayList<>(); for (List san : subjAltNames) { if (((Integer) san.get(0)).intValue() != ALTNAME_DNS) { continue; @@ -253,7 +253,7 @@ public class XmppHostnameVerifier implements HostnameVerifier { if (subjectAlternativeNames == null) { throw new CertificateException("No subject alternative names present"); } - List nonMatchingIpAltnames = new LinkedList<>(); + List nonMatchingIpAltnames = new ArrayList<>(); for (List san : subjectAlternativeNames) { if (((Integer) san.get(0)).intValue() != ALTNAME_IP) { continue; diff --git a/smack-jingle-old/build.gradle b/smack-jingle-old/build.gradle index 5651864f2..63e732bee 100644 --- a/smack-jingle-old/build.gradle +++ b/smack-jingle-old/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' +} + description = """\ Smack Jingle API. Warning: This API is beta, outdated and currenlty unmaintained.""" diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/sshare/api/OctTreeQuantizer.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/sshare/api/OctTreeQuantizer.java index bb6e7ff27..91cdd7de0 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/sshare/api/OctTreeQuantizer.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/sshare/api/OctTreeQuantizer.java @@ -76,6 +76,7 @@ public class OctTreeQuantizer implements Quantizer { private int colors = 0; private final List> colorList; + @SuppressWarnings("JdkObsolete") public OctTreeQuantizer() { setup(256); colorList = new ArrayList<>(MAX_LEVEL + 1); diff --git a/smack-legacy/build.gradle b/smack-legacy/build.gradle index 1ecec2720..12cb8b457 100644 --- a/smack-legacy/build.gradle +++ b/smack-legacy/build.gradle @@ -1,3 +1,8 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' + id 'org.igniterealtime.smack.android-conventions' +} + description = """\ Smack legacy extensions. Usually XEPs in the state 'retracted', 'rejected', 'deprecated', diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentRoster.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentRoster.java index 454221d70..c0f489e8b 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentRoster.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentRoster.java @@ -203,7 +203,7 @@ public class AgentRoster { /** * Returns the presence info for a particular agent, or null if the agent - * is unavailable (offline) or if no presence information is available.

      + * is unavailable (offline) or if no presence information is available. * * @param user a fully qualified xmpp JID. The address could be in any valid format (e.g. * "domain/resource", "user@domain" or "user@domain/resource"). diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java index 4c2e57c52..0767f7ea8 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java @@ -710,6 +710,7 @@ public class AgentSession { } } + @SuppressWarnings("JavaUtilDate") private void fireOfferRequestEvent(OfferRequestProvider.OfferRequestPacket requestPacket) { Offer offer = new Offer(this.connection, this, requestPacket.getUserID(), requestPacket.getUserJID(), this.getWorkgroupJID(), @@ -723,6 +724,7 @@ public class AgentSession { } } + @SuppressWarnings("JavaUtilDate") private void fireOfferRevokeEvent(OfferRevokeProvider.OfferRevokePacket orp) { RevokedOffer revokedOffer = new RevokedOffer(orp.getUserJID(), orp.getUserID(), this.getWorkgroupJID(), orp.getSessionID(), orp.getReason(), new Date()); diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/history/AgentChatHistory.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/history/AgentChatHistory.java index 87b03daf4..3fc5f4a1e 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/history/AgentChatHistory.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/history/AgentChatHistory.java @@ -54,6 +54,7 @@ public class AgentChatHistory extends IQ { private final List agentChatSessions = new ArrayList<>(); + @SuppressWarnings("JavaUtilDate") public AgentChatHistory(EntityBareJid agentJID, int maxSessions, Date startDate) { this(); this.agentJID = agentJID; @@ -116,6 +117,7 @@ public class AgentChatHistory extends IQ { return agentChatHistory; } + @SuppressWarnings("JavaUtilDate") private static AgentChatSession parseChatSetting(XmlPullParser parser) throws XmlPullParserException, IOException { boolean done = false; diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/QueueDetails.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/QueueDetails.java index 19d7a0e3b..f29eb7738 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/QueueDetails.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/QueueDetails.java @@ -145,6 +145,7 @@ public final class QueueDetails implements ExtensionElement { */ public static class Provider extends ExtensionElementProvider { + @SuppressWarnings("JavaUtilDate") @Override public QueueDetails parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException, diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/util/MetaDataUtils.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/util/MetaDataUtils.java index 29170b479..24370229f 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/util/MetaDataUtils.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/util/MetaDataUtils.java @@ -19,7 +19,7 @@ package org.jivesoftware.smackx.workgroup.util; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; -import java.util.Hashtable; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -45,6 +45,7 @@ public class MetaDataUtils { * @throws XmlPullParserException if an error occurs while parsing the XML. * @throws IOException if an error occurs while parsing the XML. */ + @SuppressWarnings("MixedMutabilityReturnType") public static Map> parseMetaData(XmlPullParser parser) throws XmlPullParserException, IOException { XmlPullParser.Event eventType = parser.getEventType(); @@ -52,7 +53,7 @@ public class MetaDataUtils { if ((eventType == XmlPullParser.Event.START_ELEMENT) && parser.getName().equals(MetaData.ELEMENT_NAME) && parser.getNamespace().equals(MetaData.NAMESPACE)) { - Map> metaData = new Hashtable<>(); + Map> metaData = new LinkedHashMap<>(); eventType = parser.next(); diff --git a/smack-omemo-signal-integration-test/build.gradle b/smack-omemo-signal-integration-test/build.gradle index a499edc0c..58414a4d6 100644 --- a/smack-omemo-signal-integration-test/build.gradle +++ b/smack-omemo-signal-integration-test/build.gradle @@ -1,17 +1,16 @@ -apply plugin: 'application' +plugins { + id 'org.igniterealtime.smack.java-common-conventions' + id 'org.igniterealtime.smack.application-conventions' +} description = """\ Smack integration tests for OMEMO using libsignal.""" -mainClassName = 'org.igniterealtime.smack.inttest.smack_omemo_signal.SmackOmemoSignalIntegrationTestFramework' -applicationDefaultJvmArgs = ["-enableassertions"] +application { + mainClass = 'org.igniterealtime.smack.inttest.smack_omemo_signal.SmackOmemoSignalIntegrationTestFramework' +} dependencies { api project(':smack-integration-test') api project(':smack-omemo-signal') } - -run { - // Pass all system properties down to the "application" run - systemProperties System.getProperties() -} diff --git a/smack-omemo-signal/build.gradle b/smack-omemo-signal/build.gradle index f29374f10..aa0887f94 100644 --- a/smack-omemo-signal/build.gradle +++ b/smack-omemo-signal/build.gradle @@ -1,3 +1,8 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' + id 'org.igniterealtime.smack.android-conventions' +} + description=""" Smack API for XEP-0384: OMEMO Encryption using libsignal """ @@ -8,6 +13,9 @@ dependencies { api project(":smack-omemo") implementation 'org.whispersystems:signal-protocol-java:2.8.1' + // TODO: Migrate Junit4 tests to Junit5. + testImplementation "org.junit.vintage:junit-vintage-engine:$junitVersion" + testFixturesApi(testFixtures(project(":smack-core"))) testImplementation project(path: ":smack-omemo", configuration: "testRuntime") } diff --git a/smack-omemo/build.gradle b/smack-omemo/build.gradle index bee2d806c..ca38595a0 100644 --- a/smack-omemo/build.gradle +++ b/smack-omemo/build.gradle @@ -1,3 +1,8 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' + id 'org.igniterealtime.smack.android-conventions' +} + description=""" Smack API for XEP-0384: OMEMO Encryption """ @@ -7,5 +12,8 @@ dependencies { api project(":smack-extensions") api project(":smack-experimental") + // TODO: Migrate Junit4 tests to Junit5. + testImplementation "org.junit.vintage:junit-vintage-engine:$junitVersion" + testFixturesApi(testFixtures(project(":smack-core"))) } diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/FileBasedOmemoStore.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/FileBasedOmemoStore.java index 62b742db5..89faecafc 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/FileBasedOmemoStore.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/FileBasedOmemoStore.java @@ -125,12 +125,14 @@ public abstract class FileBasedOmemoStore stack = new Stack<>(); diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java index d8e768e01..3f70ad7da 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java @@ -914,6 +914,7 @@ public abstract class OmemoService to, List payload) { super(Objects.requireNonNullNorEmpty( to, "Encrypted OpenPGP content elements must have at least one 'to' attribute."), diff --git a/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/OpenPgpContentElement.java b/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/OpenPgpContentElement.java index 974185573..07d9327cb 100644 --- a/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/OpenPgpContentElement.java +++ b/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/OpenPgpContentElement.java @@ -132,7 +132,7 @@ public abstract class OpenPgpContentElement implements ExtensionElement { * @param type of the ExtensionElement. * @return the extension, or null if it doesn't exist. */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"}) public PE getExtension(String elementName, String namespace) { if (namespace == null) { return null; diff --git a/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/PublicKeysListElement.java b/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/PublicKeysListElement.java index d4b9e81c7..780f67fc7 100644 --- a/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/PublicKeysListElement.java +++ b/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/PublicKeysListElement.java @@ -133,12 +133,13 @@ public final class PublicKeysListElement implements ExtensionElement { return xml; } + @SuppressWarnings("JavaUtilDate") @Override public int hashCode() { return getV4Fingerprint().hashCode() + 3 * getDate().hashCode(); } - @SuppressWarnings("UndefinedEquals") + @SuppressWarnings({"UndefinedEquals", "JavaUtilDate"}) // TODO: Fix the UndefinedEquals due using Date.equals(Date) @Override public boolean equals(Object o) { diff --git a/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/provider/OpenPgpContentElementProvider.java b/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/provider/OpenPgpContentElementProvider.java index 9bba1ef5e..616ac8779 100644 --- a/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/provider/OpenPgpContentElementProvider.java +++ b/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/provider/OpenPgpContentElementProvider.java @@ -1,6 +1,6 @@ /** * - * Copyright 2017-2021 Florian Schmaus, 2018 Paul Schaub. + * Copyright 2017-2024 Florian Schmaus, 2018 Paul Schaub. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,9 @@ package org.jivesoftware.smackx.ox.provider; import java.io.IOException; import java.text.ParseException; +import java.util.ArrayList; import java.util.Date; import java.util.HashSet; -import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.logging.Level; @@ -87,7 +87,7 @@ public abstract class OpenPgpContentElementProvider to = new HashSet<>(); Date timestamp = null; String rpad = null; - List payload = new LinkedList<>(); + List payload = new ArrayList<>(); outerloop: while (true) { XmlPullParser.Event tag = parser.next(); diff --git a/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/store/filebased/FileBasedOpenPgpMetadataStore.java b/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/store/filebased/FileBasedOpenPgpMetadataStore.java index 9d20e2cfa..d1f0b2d6b 100644 --- a/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/store/filebased/FileBasedOpenPgpMetadataStore.java +++ b/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/store/filebased/FileBasedOpenPgpMetadataStore.java @@ -118,6 +118,7 @@ public class FileBasedOpenPgpMetadataStore extends AbstractOpenPgpMetadataStore } } + @SuppressWarnings("JavaUtilDate") static void writeFingerprintsAndDates(Map data, File destination) throws IOException { if (data == null || data.isEmpty()) { diff --git a/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/util/OpenPgpPubSubUtil.java b/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/util/OpenPgpPubSubUtil.java index 99caf10f9..1ba31495d 100644 --- a/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/util/OpenPgpPubSubUtil.java +++ b/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/util/OpenPgpPubSubUtil.java @@ -124,6 +124,7 @@ public class OpenPgpPubSubUtil { * @throws SmackException.NotConnectedException if we are not connected. * @throws SmackException.NoResponseException if the server doesn't respond. */ + @SuppressWarnings("JavaUtilDate") public static void publishPublicKey(PepManager pepManager, PubkeyElement pubkeyElement, OpenPgpV4Fingerprint fingerprint) throws InterruptedException, PubSubException.NotALeafNodeException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException { @@ -464,8 +465,7 @@ public class OpenPgpPubSubUtil { } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException | NoSuchFieldException e) { - LOGGER.log(Level.SEVERE, "Using reflections to create a LeafNode and put it into PubSubManagers nodeMap failed.", e); - throw new AssertionError(e); + throw new LinkageError("Using reflections to create a LeafNode and put it into PubSubManagers nodeMap failed.", e); } } } diff --git a/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/OpenPgpElementTest.java b/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/OpenPgpElementTest.java index 2c54a0d55..a958d1adb 100644 --- a/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/OpenPgpElementTest.java +++ b/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/OpenPgpElementTest.java @@ -51,6 +51,7 @@ public class OpenPgpElementTest extends SmackTestSuite { private final Set recipients; // 2014-07-10T15:06:00.000+00:00 + @SuppressWarnings("JavaUtilDate") private static final Date testDate = new Date(1405004760000L); public OpenPgpElementTest() throws XmppStringprepException { diff --git a/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/OpenPgpStoreTest.java b/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/OpenPgpStoreTest.java index d64c1522c..30e3f05af 100644 --- a/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/OpenPgpStoreTest.java +++ b/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/OpenPgpStoreTest.java @@ -300,6 +300,7 @@ public class OpenPgpStoreTest extends SmackTestSuite { */ @Test + @SuppressWarnings("JavaUtilDate") public void t10_meta_emptyStoreTest() throws IOException { assertNotNull(openPgpStoreInstance1.getAnnouncedFingerprintsOf(alice)); assertTrue(openPgpStoreInstance1.getAnnouncedFingerprintsOf(alice).isEmpty()); @@ -324,6 +325,7 @@ public class OpenPgpStoreTest extends SmackTestSuite { } @Test + @SuppressWarnings("JavaUtilDate") public void t11_key_fetchDateTest() throws IOException { Map fetchDates1 = openPgpStoreInstance1.getPublicKeyFetchDates(alice); diff --git a/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/PainlessOpenPgpProviderTest.java b/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/PainlessOpenPgpProviderTest.java index 5f1210367..41319bd6f 100644 --- a/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/PainlessOpenPgpProviderTest.java +++ b/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/PainlessOpenPgpProviderTest.java @@ -72,6 +72,7 @@ public class PainlessOpenPgpProviderTest extends SmackTestSuite { } @Test + @SuppressWarnings("JavaUtilDate") public void encryptDecryptTest() throws PGPException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException, IOException, MissingUserIdOnKeyException, XmlPullParserException { // Initialize diff --git a/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/PublicKeysListElementTest.java b/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/PublicKeysListElementTest.java index 319c60bcf..eb7f3922c 100644 --- a/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/PublicKeysListElementTest.java +++ b/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/PublicKeysListElementTest.java @@ -70,6 +70,7 @@ public class PublicKeysListElementTest extends SmackTestSuite { } @Test + @SuppressWarnings("JavaUtilDate") public void listBuilderRefusesDuplicatesTest() { PublicKeysListElement.Builder builder = PublicKeysListElement.builder(); String fp40 = "49545320414c4c2041424f555420444120484558"; diff --git a/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingManagerTest.java b/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingManagerTest.java index 7854aedce..668a14204 100644 --- a/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingManagerTest.java +++ b/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingManagerTest.java @@ -66,6 +66,7 @@ public class OXInstantMessagingManagerTest extends SmackTestSuite { } @Test + @SuppressWarnings("JavaUtilDate") public void test() throws IOException, PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException, SmackException, MissingUserIdOnKeyException, InterruptedException, XMPPException, XmlPullParserException { diff --git a/smack-repl/build.gradle b/smack-repl/build.gradle index a7e1017d0..9b60cd9fb 100644 --- a/smack-repl/build.gradle +++ b/smack-repl/build.gradle @@ -1,12 +1,13 @@ plugins { - id "com.github.alisiikh.scalastyle_2.12" version "2.1.0" + id 'org.igniterealtime.smack.java-common-conventions' + id "com.github.alisiikh.scalastyle" version "3.5.0" } description = """\ A REPL (Read-Eval-Print-Loop) for Smack, or, in other words, a CLI (Command Line Interface) for Smack.""" apply plugin: 'scala' -apply plugin: 'com.github.alisiikh.scalastyle_2.12' +apply plugin: 'com.github.alisiikh.scalastyle' ext { scalaVersion = '2.13.13' @@ -19,13 +20,13 @@ dependencies { implementation "com.lihaoyi:ammonite_$scalaVersion:3.0.0-M1" } -scalaStyle { +scalastyle { config = new File(rootConfigDir, 'scalaStyle.xml') verbose = true - failOnViolation = true + failOnWarning = true } -check.dependsOn(scalaStyleCheck) +check.dependsOn(scalastyleCheck) task printClasspath(dependsOn: assemble) { doLast { diff --git a/smack-resolver-dnsjava/build.gradle b/smack-resolver-dnsjava/build.gradle index b17683ecc..b4e6b85cf 100644 --- a/smack-resolver-dnsjava/build.gradle +++ b/smack-resolver-dnsjava/build.gradle @@ -1,3 +1,8 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' + id 'org.igniterealtime.smack.android-conventions' +} + description = """\ DNS SRV with dnsjava Use dnsjava for DNS SRV lookups.""" diff --git a/smack-resolver-javax/build.gradle b/smack-resolver-javax/build.gradle index 4caefb6f5..f724be154 100644 --- a/smack-resolver-javax/build.gradle +++ b/smack-resolver-javax/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' +} + description = """\ DNS SRV with Java7 Use javax.naming for DNS SRV lookups. The javax.naming API is availabe in JavaSE diff --git a/smack-resolver-javax/src/main/java/org/jivesoftware/smack/util/dns/javax/JavaxResolver.java b/smack-resolver-javax/src/main/java/org/jivesoftware/smack/util/dns/javax/JavaxResolver.java index 9e78b34b8..96cd9771a 100644 --- a/smack-resolver-javax/src/main/java/org/jivesoftware/smack/util/dns/javax/JavaxResolver.java +++ b/smack-resolver-javax/src/main/java/org/jivesoftware/smack/util/dns/javax/JavaxResolver.java @@ -1,6 +1,6 @@ /** * - * Copyright 2013-2020 Florian Schmaus + * Copyright 2013-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,6 +45,7 @@ import org.minidns.record.SRV; * @author Florian Schmaus * */ +@SuppressWarnings("JdkObsolete") public class JavaxResolver extends DNSResolver implements SmackInitializer { private static JavaxResolver instance; diff --git a/smack-resolver-minidns-dox/build.gradle b/smack-resolver-minidns-dox/build.gradle index de740cf84..f8ebf7d3b 100644 --- a/smack-resolver-minidns-dox/build.gradle +++ b/smack-resolver-minidns-dox/build.gradle @@ -1,3 +1,8 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' + id 'org.igniterealtime.smack.android-conventions' +} + description = """\ DNS over XMPP (DoX) support using MiniDNS.""" diff --git a/smack-resolver-minidns/build.gradle b/smack-resolver-minidns/build.gradle index 22809986c..c1fb68a28 100644 --- a/smack-resolver-minidns/build.gradle +++ b/smack-resolver-minidns/build.gradle @@ -1,3 +1,8 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' + id 'org.igniterealtime.smack.android-conventions' +} + description = """\ DNS SRV with minidns Use minidns for DNS SRV lookups. For platforms that don't provide the diff --git a/smack-sasl-javax/build.gradle b/smack-sasl-javax/build.gradle index e6fffd631..9f2eecc89 100644 --- a/smack-sasl-javax/build.gradle +++ b/smack-sasl-javax/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' +} + description = """\ SASL with javax.security.sasl Use javax.security.sasl for SASL.""" diff --git a/smack-sasl-provided/build.gradle b/smack-sasl-provided/build.gradle index a9f3724d0..65f10b3b1 100644 --- a/smack-sasl-provided/build.gradle +++ b/smack-sasl-provided/build.gradle @@ -1,3 +1,8 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' + id 'org.igniterealtime.smack.android-conventions' +} + description = """\ SASL with Smack provided code Use Smack provided code for SASL.""" diff --git a/smack-streammanagement/build.gradle b/smack-streammanagement/build.gradle index c06c423d9..73eb2139e 100644 --- a/smack-streammanagement/build.gradle +++ b/smack-streammanagement/build.gradle @@ -1,3 +1,8 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' + id 'org.igniterealtime.smack.android-conventions' +} + description = """\ Smack support for XMPP Stream Management (XEP-0198).""" diff --git a/smack-tcp/build.gradle b/smack-tcp/build.gradle index a0cffad6b..db2ee6bc2 100644 --- a/smack-tcp/build.gradle +++ b/smack-tcp/build.gradle @@ -1,3 +1,8 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' + id 'org.igniterealtime.smack.android-conventions' +} + description = """\ Smack for standard XMPP connections over TCP.""" diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java index 87ce7c647..aef1b27f0 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java @@ -31,7 +31,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.LinkedHashSet; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; @@ -415,7 +414,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { // bind IQ may trigger a SM ack request, which would be invalid in the pre resource bound state. smEnabledSyncPoint = false; - List previouslyUnackedStanzas = new LinkedList(); + List previouslyUnackedStanzas = new ArrayList(); if (unacknowledgedStanzas != null) { // There was a previous connection with SM enabled but that was either not resumable or // failed to resume. Make sure that we (re-)send the unacknowledged stanzas. diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XmppTcpTransportModule.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XmppTcpTransportModule.java index 2feb626d3..fabfa4d6f 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XmppTcpTransportModule.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XmppTcpTransportModule.java @@ -1,6 +1,6 @@ /** * - * Copyright 2019-2021 Florian Schmaus + * Copyright 2019-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -369,7 +369,7 @@ public class XmppTcpTransportModule extends ModularXmppClientToServerConnectionM newPendingOutputFilterData |= outputResult.pendingFilterData; outputFilterInputData = outputResult.filteredOutputData; if (outputFilterInputData != null) { - outputFilterInputData.flip(); + ((java.nio.Buffer) outputFilterInputData).flip(); } } @@ -459,7 +459,7 @@ public class XmppTcpTransportModule extends ModularXmppClientToServerConnectionM } int bytesRead; - incomingBuffer.clear(); + ((java.nio.Buffer) incomingBuffer).clear(); try { bytesRead = selectedSocketChannel.read(incomingBuffer); } catch (IOException e) { @@ -503,7 +503,7 @@ public class XmppTcpTransportModule extends ModularXmppClientToServerConnectionM ByteBuffer filteredIncomingBuffer = incomingBuffer; for (ListIterator it = connectionInternal.getXmppInputOutputFilterEndIterator(); it.hasPrevious();) { - filteredIncomingBuffer.flip(); + ((java.nio.Buffer) filteredIncomingBuffer).flip(); ByteBuffer newFilteredIncomingBuffer; try { @@ -518,7 +518,8 @@ public class XmppTcpTransportModule extends ModularXmppClientToServerConnectionM filteredIncomingBuffer = newFilteredIncomingBuffer; } - final int bytesReadAfterFilter = filteredIncomingBuffer.flip().remaining(); + ((java.nio.Buffer) filteredIncomingBuffer).flip(); + final int bytesReadAfterFilter = filteredIncomingBuffer.remaining(); totalBytesReadAfterFilter += bytesReadAfterFilter; @@ -980,7 +981,7 @@ public class XmppTcpTransportModule extends ModularXmppClientToServerConnectionM ByteBuffer[] outputDataArray = pendingOutputData.toArray(new ByteBuffer[pendingOutputData.size()]); - myNetData.clear(); + ((java.nio.Buffer) myNetData).clear(); while (true) { SSLEngineResult result; @@ -1037,7 +1038,7 @@ public class XmppTcpTransportModule extends ModularXmppClientToServerConnectionM newCapacity = 2 * myNetData.capacity(); } ByteBuffer newMyNetData = ByteBuffer.allocateDirect(newCapacity); - myNetData.flip(); + ((java.nio.Buffer) myNetData).flip(); newMyNetData.put(myNetData); myNetData = newMyNetData; continue; @@ -1060,12 +1061,12 @@ public class XmppTcpTransportModule extends ModularXmppClientToServerConnectionM int accumulatedDataBytes = pendingInputData.remaining() + inputData.remaining(); accumulatedData = ByteBuffer.allocate(accumulatedDataBytes); accumulatedData.put(pendingInputData) - .put(inputData) - .flip(); + .put(inputData); + ((java.nio.Buffer) accumulatedData).flip(); pendingInputData = null; } - peerAppData.clear(); + ((java.nio.Buffer) peerAppData).clear(); while (true) { SSLEngineResult result; @@ -1143,7 +1144,8 @@ public class XmppTcpTransportModule extends ModularXmppClientToServerConnectionM // higher layer. That is, here 'byteBuffer' is typically 'incomingBuffer', which is a direct buffer only // allocated once per connection for performance reasons and hence re-used for read() calls. pendingInputData = ByteBuffer.allocate(byteBuffer.remaining()); - pendingInputData.put(byteBuffer).flip(); + pendingInputData.put(byteBuffer); + ((java.nio.Buffer) pendingInputData).flip(); pendingInputFilterData = pendingInputData.hasRemaining(); } diff --git a/smack-websocket-java11/build.gradle b/smack-websocket-java11/build.gradle index 9439bad20..c019f214c 100644 --- a/smack-websocket-java11/build.gradle +++ b/smack-websocket-java11/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' +} + description = """\ Smack for XMPP connections over WebSocket (RFC 7395) using java.net.http.WebSocket.""" diff --git a/smack-websocket-okhttp/build.gradle b/smack-websocket-okhttp/build.gradle index 6f83f2c83..9e7b2fb46 100644 --- a/smack-websocket-okhttp/build.gradle +++ b/smack-websocket-okhttp/build.gradle @@ -1,3 +1,8 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' + id 'org.igniterealtime.smack.android-conventions' +} + description = """\ Smack for XMPP connections over WebSocket (RFC 7395) using OkHttp.""" diff --git a/smack-websocket/build.gradle b/smack-websocket/build.gradle index 1ef60c233..73dfab23b 100644 --- a/smack-websocket/build.gradle +++ b/smack-websocket/build.gradle @@ -1,3 +1,8 @@ +plugins { + id 'org.igniterealtime.smack.java-common-conventions' + id 'org.igniterealtime.smack.android-conventions' +} + description = """\ Smack for XMPP connections over WebSocket (RFC 7395).""" diff --git a/smack-xmlparser-stax/build.gradle b/smack-xmlparser-stax/build.gradle index b25ce2e9a..9cc67deda 100644 --- a/smack-xmlparser-stax/build.gradle +++ b/smack-xmlparser-stax/build.gradle @@ -1,7 +1,6 @@ -// Note that this is also declared in the main build.gradle for -// subprojects, but since evaluationDependsOnChildren is enabled we -// need to declare it here too to have bundle{bnd{...}} available -apply plugin: 'biz.aQute.bnd.builder' +plugins { + id 'org.igniterealtime.smack.java-common-conventions' +} description = """\ Smack XML parser using Stax.""" diff --git a/smack-xmlparser-xpp3/build.gradle b/smack-xmlparser-xpp3/build.gradle index f0a9f56c6..8c5063117 100644 --- a/smack-xmlparser-xpp3/build.gradle +++ b/smack-xmlparser-xpp3/build.gradle @@ -1,7 +1,7 @@ -// Note that this is also declared in the main build.gradle for -// subprojects, but since evaluationDependsOnChildren is enabled we -// need to declare it here too to have bundle{bnd{...}} available -apply plugin: 'biz.aQute.bnd.builder' +plugins { + id 'org.igniterealtime.smack.java-common-conventions' + id 'org.igniterealtime.smack.android-conventions' +} description = """\ Smack XML parser using XPP3.""" diff --git a/smack-xmlparser/build.gradle b/smack-xmlparser/build.gradle index 513a2b153..9686ae87b 100644 --- a/smack-xmlparser/build.gradle +++ b/smack-xmlparser/build.gradle @@ -1,7 +1,7 @@ -// Note that this is also declared in the main build.gradle for -// subprojects, but since evaluationDependsOnChildren is enabled we -// need to declare it here too to have bundle{bnd{...}} available -apply plugin: 'biz.aQute.bnd.builder' +plugins { + id 'org.igniterealtime.smack.java-common-conventions' + id 'org.igniterealtime.smack.android-conventions' +} description = """\ Smack XML parser fundamentals""" From 2eddf1949a25dbf46b27f04852325eeee7b34650 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 25 Sep 2024 15:15:04 +0200 Subject: [PATCH 135/150] [github ci] Build also with Java 21 --- .github/workflows/ci.yml | 3 ++- .../java/org/jivesoftware/smack/AbstractXMPPConnection.java | 1 + .../java/org/jivesoftware/smack/ConnectionConfiguration.java | 1 + .../smack/c2s/ModularXmppClientToServerConnection.java | 1 + .../java/org/jivesoftware/smack/packet/EmptyResultIQ.java | 3 ++- .../src/main/java/org/jivesoftware/smack/packet/IQ.java | 2 +- .../src/main/java/org/jivesoftware/smack/packet/Session.java | 1 + .../src/main/java/org/jivesoftware/smack/packet/Stanza.java | 2 +- .../src/main/java/org/jivesoftware/smack/proxy/ProxyInfo.java | 1 + .../java/org/jivesoftware/smack/util/XmlStringBuilder.java | 2 ++ .../java/org/jivesoftware/smack/DummyConnection.java | 3 ++- .../org/jivesoftware/smackx/debugger/EnhancedDebugger.java | 1 + .../java/org/jivesoftware/smackx/carbons/packet/Carbon.java | 4 +++- .../main/java/org/jivesoftware/smackx/dox/element/DnsIq.java | 3 ++- .../org/jivesoftware/smackx/httpfileupload/element/Slot.java | 1 + .../smackx/httpfileupload/element/SlotRequest.java | 1 + .../smackx/iot/control/element/IoTSetRequest.java | 3 ++- .../smackx/iot/data/element/IoTDataReadOutAccepted.java | 4 +++- .../smackx/iot/discovery/element/IoTUnregister.java | 3 ++- .../smackx/iot/provisioning/element/ClearCache.java | 3 ++- .../smackx/iot/provisioning/element/ClearCacheResponse.java | 4 +++- .../java/org/jivesoftware/smackx/mam/element/MamPrefsIQ.java | 1 + .../java/org/jivesoftware/smackx/mam/element/MamQueryIQ.java | 2 ++ .../smackx/muclight/element/MUCLightAffiliationsIQ.java | 1 + .../smackx/muclight/element/MUCLightChangeAffiliationsIQ.java | 1 + .../smackx/muclight/element/MUCLightCreateIQ.java | 1 + .../smackx/muclight/element/MUCLightDestroyIQ.java | 1 + .../smackx/muclight/element/MUCLightGetAffiliationsIQ.java | 1 + .../smackx/muclight/element/MUCLightGetConfigsIQ.java | 1 + .../smackx/muclight/element/MUCLightGetInfoIQ.java | 1 + .../smackx/muclight/element/MUCLightSetConfigsIQ.java | 1 + .../element/DisablePushNotificationsIQ.java | 1 + .../push_notifications/element/EnablePushNotificationsIQ.java | 1 + .../jivesoftware/smackx/blocking/element/BlockContactsIQ.java | 1 + .../smackx/blocking/element/UnblockContactsIQ.java | 1 + .../org/jivesoftware/smackx/bytestreams/ibb/packet/Close.java | 1 + .../org/jivesoftware/smackx/bytestreams/ibb/packet/Data.java | 1 + .../org/jivesoftware/smackx/bytestreams/ibb/packet/Open.java | 1 + .../jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java | 1 + .../smackx/bytestreams/socks5/packet/Bytestream.java | 1 + .../org/jivesoftware/smackx/commands/AdHocCommandHandler.java | 1 + .../org/jivesoftware/smackx/iqlast/packet/LastActivity.java | 2 ++ .../jivesoftware/smackx/iqprivate/packet/PrivateDataIQ.java | 4 +++- .../smackx/jingle/transports/JingleTransportManager.java | 1 + .../main/java/org/jivesoftware/smackx/ping/packet/Ping.java | 3 ++- .../java/org/jivesoftware/smackx/pubsub/packet/PubSub.java | 1 + .../main/java/org/jivesoftware/smackx/time/packet/Time.java | 3 ++- .../java/org/jivesoftware/smackx/xdata/form/FillableForm.java | 1 + .../java/org/jivesoftware/smack/StreamManagementTest.java | 3 ++- .../smackx/muc/MultiUserChatLowLevelIntegrationTest.java | 1 + .../org/jivesoftware/smackx/jingleold/mediaimpl/JMFInit.java | 1 + .../smackx/jingleold/mediaimpl/jmf/AudioMediaSession.java | 1 + .../smackx/jingleold/mediaimpl/jspeex/AudioMediaSession.java | 1 + .../smackx/jingleold/mediaimpl/sshare/ScreenShareSession.java | 1 + .../smackx/jingleold/mediaimpl/sshare/api/ImageReceiver.java | 1 + .../jingleold/mediaimpl/sshare/api/OctTreeQuantizer.java | 2 +- .../smackx/jingleold/mediaimpl/test/TestMediaSession.java | 1 + .../org/jivesoftware/smackx/jingleold/nat/FixedResolver.java | 1 + .../org/jivesoftware/smackx/jingleold/nat/ICEResolver.java | 1 + .../jivesoftware/smackx/jingleold/nat/TcpUdpBridgeClient.java | 1 + .../jivesoftware/smackx/jingleold/nat/TcpUdpBridgeServer.java | 1 + .../java/org/jivesoftware/smackx/jingleold/packet/Jingle.java | 4 ++++ .../smackx/jingleold/packet/JingleContentDescription.java | 1 + .../smackx/jingleold/packet/JingleContentInfo.java | 1 + .../smackx/jingleold/packet/JingleDescription.java | 1 + .../jivesoftware/smackx/jingleold/packet/JingleTransport.java | 4 ++++ .../smackx/workgroup/packet/DepartQueuePacket.java | 1 + .../jivesoftware/smackx/workgroup/settings/ChatSetting.java | 1 + .../jivesoftware/smackx/workgroup/settings/ChatSettings.java | 1 + .../org/jivesoftware/smackx/workgroup/user/Workgroup.java | 1 + .../jivesoftware/smackx/xroster/packet/RosterExchange.java | 1 + .../java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java | 1 + 72 files changed, 99 insertions(+), 17 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5ddb006d2..b1019ea4b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,8 +11,9 @@ jobs: matrix: java: - 17 + - 21 env: - PRIMARY_JAVA_VERSION: 17 + PRIMARY_JAVA_VERSION: 21 steps: - name: Checkout 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 e29ed25f8..a3fc2f941 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java @@ -388,6 +388,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { * * @param configuration The configuration which is used to establish the connection. */ + @SuppressWarnings("this-escape") protected AbstractXMPPConnection(ConnectionConfiguration configuration) { saslAuthentication = new SASLAuthentication(this, configuration); config = configuration; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java b/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java index 098f4b6a1..e9d8afe45 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java @@ -672,6 +672,7 @@ public abstract class ConnectionConfiguration { private boolean compressionEnabled = false; private StanzaIdSourceFactory stanzaIdSourceFactory = new StandardStanzaIdSource.Factory(); + @SuppressWarnings("this-escape") protected Builder() { if (SmackConfiguration.DEBUG) { enableDefaultDebugger(); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/c2s/ModularXmppClientToServerConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/c2s/ModularXmppClientToServerConnection.java index 0ece95aa2..5f060311a 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/c2s/ModularXmppClientToServerConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/c2s/ModularXmppClientToServerConnection.java @@ -658,6 +658,7 @@ public final class ModularXmppClientToServerConnection extends AbstractXMPPConne updateOutgoingStreamXmlEnvironmentOnStreamOpen(streamOpen); } + @SuppressWarnings("this-escape") public static class DisconnectedStateDescriptor extends StateDescriptor { protected DisconnectedStateDescriptor() { super(DisconnectedState.class, StateDescriptor.Property.finalState); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java index a4d977ac3..246e9de06 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2014-2023 Florian Schmaus + * Copyright © 2014-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ public class EmptyResultIQ extends IQ { } // TODO: Deprecate when stanza builder and parsing logic is ready. + @SuppressWarnings("this-escape") public EmptyResultIQ() { super((String) null, null); setType(IQ.Type.result); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java index 8f87dae63..98f9880f3 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java @@ -88,7 +88,7 @@ public abstract class IQ extends Stanza implements IqView { } @Override - public Type getType() { + public final Type getType() { return type; } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/Session.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/Session.java index 48e0330c6..7e6331bb8 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/Session.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/Session.java @@ -39,6 +39,7 @@ public class Session extends SimpleIQ { public static final String ELEMENT = "session"; public static final String NAMESPACE = "urn:ietf:params:xml:ns:xmpp-session"; + @SuppressWarnings("this-escape") public Session() { super(ELEMENT, NAMESPACE); setType(IQ.Type.set); 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 a6d55ca47..88c30bbfa 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 @@ -203,7 +203,7 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { * @param to who the packet is being sent to. */ // TODO: Mark this as deprecated once StanzaBuilder is ready and all call sites are gone. - public void setTo(Jid to) { + public final void setTo(Jid to) { this.to = to; } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/proxy/ProxyInfo.java b/smack-core/src/main/java/org/jivesoftware/smack/proxy/ProxyInfo.java index 402a106a4..90433c5c8 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/proxy/ProxyInfo.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/proxy/ProxyInfo.java @@ -41,6 +41,7 @@ public class ProxyInfo { private ProxyType proxyType; private final ProxySocketConnection proxySocketConnection; + @SuppressWarnings("this-escape") public ProxyInfo(ProxyType pType, String pHost, int pPort, String pUser, String pPass) { this.proxyType = pType; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java index 9eec876c4..5c327157b 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java @@ -47,6 +47,7 @@ public class XmlStringBuilder implements Appendable, CharSequence, Element { this(pe, null); } + @SuppressWarnings("this-escape") public XmlStringBuilder(NamedElement e) { this(); halfOpenElement(e.getElementName()); @@ -56,6 +57,7 @@ public class XmlStringBuilder implements Appendable, CharSequence, Element { this(element.getElementName(), element.getNamespace(), element.getLanguage(), enclosingXmlEnvironment); } + @SuppressWarnings("this-escape") public XmlStringBuilder(String elementName, String xmlNs, String xmlLang, XmlEnvironment enclosingXmlEnvironment) { sb = new LazyStringBuilder(); halfOpenElement(elementName); diff --git a/smack-core/src/testFixtures/java/org/jivesoftware/smack/DummyConnection.java b/smack-core/src/testFixtures/java/org/jivesoftware/smack/DummyConnection.java index 2faca2ebc..320bb1f9e 100644 --- a/smack-core/src/testFixtures/java/org/jivesoftware/smack/DummyConnection.java +++ b/smack-core/src/testFixtures/java/org/jivesoftware/smack/DummyConnection.java @@ -1,6 +1,6 @@ /** * - * Copyright 2010 Jive Software, 2022 Florian Schmaus. + * Copyright 2010 Jive Software, 2022-2024 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -82,6 +82,7 @@ public class DummyConnection extends AbstractXMPPConnection { } } + @SuppressWarnings("this-escape") public DummyConnection(DummyConnectionConfiguration configuration) { super(configuration); diff --git a/smack-debug/src/main/java/org/jivesoftware/smackx/debugger/EnhancedDebugger.java b/smack-debug/src/main/java/org/jivesoftware/smackx/debugger/EnhancedDebugger.java index 23eba68ec..e57b4aaaa 100644 --- a/smack-debug/src/main/java/org/jivesoftware/smackx/debugger/EnhancedDebugger.java +++ b/smack-debug/src/main/java/org/jivesoftware/smackx/debugger/EnhancedDebugger.java @@ -178,6 +178,7 @@ public class EnhancedDebugger extends SmackDebugger { JTabbedPane tabbedPane; + @SuppressWarnings("this-escape") public EnhancedDebugger(XMPPConnection connection) { super(connection); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/carbons/packet/Carbon.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/carbons/packet/Carbon.java index 8f303cdff..77ef518f6 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/carbons/packet/Carbon.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/carbons/packet/Carbon.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2014 Florian Schmaus + * Copyright © 2014-2024 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,6 +27,7 @@ public class Carbon { public static class Enable extends SimpleIQ { public static final String ELEMENT = "enable"; + @SuppressWarnings("this-escape") public Enable() { super(ELEMENT, NAMESPACE); setType(Type.set); @@ -37,6 +38,7 @@ public class Carbon { public static class Disable extends SimpleIQ { public static final String ELEMENT = "disable"; + @SuppressWarnings("this-escape") public Disable() { super(ELEMENT, NAMESPACE); setType(Type.set); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/dox/element/DnsIq.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/dox/element/DnsIq.java index 77c626eae..590906549 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/dox/element/DnsIq.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/dox/element/DnsIq.java @@ -1,6 +1,6 @@ /** * - * Copyright 2019 Florian Schmaus + * Copyright 2019-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,6 +43,7 @@ public class DnsIq extends IQ { this(new DnsMessage(dnsMessage)); } + @SuppressWarnings("this-escape") public DnsIq(DnsMessage dnsQuery, Jid to) { this(dnsQuery); setTo(to); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/httpfileupload/element/Slot.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/httpfileupload/element/Slot.java index 274e59bc0..48c61bec7 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/httpfileupload/element/Slot.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/httpfileupload/element/Slot.java @@ -46,6 +46,7 @@ public class Slot extends IQ { this(putUrl, getUrl, headers, NAMESPACE); } + @SuppressWarnings("this-escape") protected Slot(URL putUrl, URL getUrl, Map headers, String namespace) { super(ELEMENT, namespace); setType(Type.result); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/httpfileupload/element/SlotRequest.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/httpfileupload/element/SlotRequest.java index 961fc27e1..0fa8b484c 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/httpfileupload/element/SlotRequest.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/httpfileupload/element/SlotRequest.java @@ -53,6 +53,7 @@ public class SlotRequest extends IQ { this(uploadServiceAddress, filename, size, contentType, NAMESPACE); } + @SuppressWarnings("this-escape") protected SlotRequest(DomainBareJid uploadServiceAddress, String filename, long size, String contentType, String namespace) { super(ELEMENT, namespace); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/IoTSetRequest.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/IoTSetRequest.java index cd6d0b553..a3dad0268 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/IoTSetRequest.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/IoTSetRequest.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2016-2017 Florian Schmaus + * Copyright © 2016-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ public class IoTSetRequest extends IQ { private final Collection setData; + @SuppressWarnings("this-escape") public IoTSetRequest(Collection setData) { super(ELEMENT, NAMESPACE); setType(Type.set); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/element/IoTDataReadOutAccepted.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/element/IoTDataReadOutAccepted.java index 20d0a125d..279476cd2 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/element/IoTDataReadOutAccepted.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/element/IoTDataReadOutAccepted.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2016 Florian Schmaus + * Copyright © 2016-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,7 @@ public class IoTDataReadOutAccepted extends IQ { private final boolean queued; + @SuppressWarnings("this-escape") public IoTDataReadOutAccepted(int seqNr, boolean queued) { super(ELEMENT, NAMESPACE); this.seqNr = seqNr; @@ -37,6 +38,7 @@ public class IoTDataReadOutAccepted extends IQ { setType(Type.result); } + @SuppressWarnings("this-escape") public IoTDataReadOutAccepted(IoTDataRequest dataRequest) { this(dataRequest.getSequenceNr(), false); setStanzaId(dataRequest.getStanzaId()); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/element/IoTUnregister.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/element/IoTUnregister.java index bdc536f97..3b510e55f 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/element/IoTUnregister.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/element/IoTUnregister.java @@ -1,6 +1,6 @@ /** * - * Copyright 2016 Florian Schmaus + * Copyright 2016-2024 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,6 +27,7 @@ public class IoTUnregister extends IQ { private final NodeInfo nodeInfo; + @SuppressWarnings("this-escape") public IoTUnregister(NodeInfo nodeInfo) { super(ELEMENT, NAMESPACE); this.nodeInfo = nodeInfo; diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/element/ClearCache.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/element/ClearCache.java index fe98b32b3..d17e46c94 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/element/ClearCache.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/element/ClearCache.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2016 Florian Schmaus + * Copyright © 2016-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ public class ClearCache extends SimpleIQ { public static final String ELEMENT = "clearCache"; public static final String NAMESPACE = Constants.IOT_PROVISIONING_NAMESPACE; + @SuppressWarnings("this-escape") public ClearCache() { super(ELEMENT, NAMESPACE); // IQs are always of type 'get' (XEP-0324 § 3.5.1, see also the XEPs history remarks) diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/element/ClearCacheResponse.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/element/ClearCacheResponse.java index 1c229d153..1abfb731c 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/element/ClearCacheResponse.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/element/ClearCacheResponse.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2016 Florian Schmaus + * Copyright © 2016-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,12 +23,14 @@ public class ClearCacheResponse extends SimpleIQ { public static final String ELEMENT = "clearCacheResponse"; public static final String NAMESPACE = Constants.IOT_PROVISIONING_NAMESPACE; + @SuppressWarnings("this-escape") public ClearCacheResponse() { super(ELEMENT, NAMESPACE); // IQs are always of type 'result' (XEP-0324 § 3.5.1, see also the XEPs history remarks) setType(Type.result); } + @SuppressWarnings("this-escape") public ClearCacheResponse(ClearCache clearCacheRequest) { this(); setStanzaId(clearCacheRequest.getStanzaId()); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/mam/element/MamPrefsIQ.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/mam/element/MamPrefsIQ.java index e5898f4c3..1a5535135 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/mam/element/MamPrefsIQ.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/mam/element/MamPrefsIQ.java @@ -81,6 +81,7 @@ public class MamPrefsIQ extends IQ { * @param neverJids TODO javadoc me please * @param defaultBehavior TODO javadoc me please */ + @SuppressWarnings("this-escape") public MamPrefsIQ(MamVersion version, List alwaysJids, List neverJids, DefaultBehavior defaultBehavior) { super(ELEMENT, version.getNamespace()); setType(Type.set); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/mam/element/MamQueryIQ.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/mam/element/MamQueryIQ.java index 3909b077c..17b8a5cae 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/mam/element/MamQueryIQ.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/mam/element/MamQueryIQ.java @@ -45,6 +45,7 @@ public class MamQueryIQ extends IQ { * @param version TODO javadoc me please * @param queryId TODO javadoc me please */ + @SuppressWarnings("this-escape") public MamQueryIQ(MamVersion version, String queryId) { this(version, queryId, null, null); setType(IQ.Type.get); @@ -79,6 +80,7 @@ public class MamQueryIQ extends IQ { * @param node TODO javadoc me please * @param dataForm TODO javadoc me please */ + @SuppressWarnings("this-escape") public MamQueryIQ(MamVersion version, String queryId, String node, DataForm dataForm) { super(ELEMENT, version.getNamespace()); this.queryId = queryId; diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightAffiliationsIQ.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightAffiliationsIQ.java index c9e0ead62..e1e8fcdf4 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightAffiliationsIQ.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightAffiliationsIQ.java @@ -48,6 +48,7 @@ public class MUCLightAffiliationsIQ extends IQ { * @param version TODO javadoc me please * @param affiliations TODO javadoc me please */ + @SuppressWarnings("this-escape") public MUCLightAffiliationsIQ(String version, HashMap affiliations) { super(ELEMENT, NAMESPACE); this.version = version; diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightChangeAffiliationsIQ.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightChangeAffiliationsIQ.java index 494a7a4d7..2898ea8b6 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightChangeAffiliationsIQ.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightChangeAffiliationsIQ.java @@ -47,6 +47,7 @@ public class MUCLightChangeAffiliationsIQ extends IQ { * @param room TODO javadoc me please * @param affiliations TODO javadoc me please */ + @SuppressWarnings("this-escape") public MUCLightChangeAffiliationsIQ(Jid room, HashMap affiliations) { super(ELEMENT, NAMESPACE); this.setType(Type.set); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightCreateIQ.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightCreateIQ.java index d15d47db5..afd8efd90 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightCreateIQ.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightCreateIQ.java @@ -53,6 +53,7 @@ public class MUCLightCreateIQ extends IQ { * @param customConfigs TODO javadoc me please * @param occupants TODO javadoc me please */ + @SuppressWarnings("this-escape") public MUCLightCreateIQ(EntityJid room, String roomName, String subject, HashMap customConfigs, List occupants) { super(ELEMENT, NAMESPACE); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightDestroyIQ.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightDestroyIQ.java index 8198007cf..6606ae035 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightDestroyIQ.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightDestroyIQ.java @@ -38,6 +38,7 @@ public class MUCLightDestroyIQ extends IQ { * * @param roomJid TODO javadoc me please */ + @SuppressWarnings("this-escape") public MUCLightDestroyIQ(Jid roomJid) { super(ELEMENT, NAMESPACE); this.setType(Type.set); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightGetAffiliationsIQ.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightGetAffiliationsIQ.java index 67cd26481..70249914c 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightGetAffiliationsIQ.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightGetAffiliationsIQ.java @@ -41,6 +41,7 @@ public class MUCLightGetAffiliationsIQ extends IQ { * @param roomJid TODO javadoc me please * @param version TODO javadoc me please */ + @SuppressWarnings("this-escape") public MUCLightGetAffiliationsIQ(Jid roomJid, String version) { super(ELEMENT, NAMESPACE); this.version = version; diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightGetConfigsIQ.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightGetConfigsIQ.java index 15ce3e1f9..aff4283ee 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightGetConfigsIQ.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightGetConfigsIQ.java @@ -41,6 +41,7 @@ public class MUCLightGetConfigsIQ extends IQ { * @param roomJid TODO javadoc me please * @param version TODO javadoc me please */ + @SuppressWarnings("this-escape") public MUCLightGetConfigsIQ(Jid roomJid, String version) { super(ELEMENT, NAMESPACE); this.version = version; diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightGetInfoIQ.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightGetInfoIQ.java index 112ec1935..6e3d1daa0 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightGetInfoIQ.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightGetInfoIQ.java @@ -41,6 +41,7 @@ public class MUCLightGetInfoIQ extends IQ { * @param roomJid TODO javadoc me please * @param version TODO javadoc me please */ + @SuppressWarnings("this-escape") public MUCLightGetInfoIQ(Jid roomJid, String version) { super(ELEMENT, NAMESPACE); this.version = version; diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightSetConfigsIQ.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightSetConfigsIQ.java index 0751b582f..6ab25a9ed 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightSetConfigsIQ.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightSetConfigsIQ.java @@ -49,6 +49,7 @@ public class MUCLightSetConfigsIQ extends IQ { * @param subject TODO javadoc me please * @param customConfigs TODO javadoc me please */ + @SuppressWarnings("this-escape") public MUCLightSetConfigsIQ(Jid roomJid, String roomName, String subject, HashMap customConfigs) { super(ELEMENT, NAMESPACE); this.roomName = roomName; diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/push_notifications/element/DisablePushNotificationsIQ.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/push_notifications/element/DisablePushNotificationsIQ.java index bedf8be02..08342811b 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/push_notifications/element/DisablePushNotificationsIQ.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/push_notifications/element/DisablePushNotificationsIQ.java @@ -43,6 +43,7 @@ public class DisablePushNotificationsIQ extends IQ { private final Jid jid; private final String node; + @SuppressWarnings("this-escape") public DisablePushNotificationsIQ(Jid jid, String node) { super(ELEMENT, NAMESPACE); this.jid = jid; diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/push_notifications/element/EnablePushNotificationsIQ.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/push_notifications/element/EnablePushNotificationsIQ.java index 428b41b67..643de425a 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/push_notifications/element/EnablePushNotificationsIQ.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/push_notifications/element/EnablePushNotificationsIQ.java @@ -53,6 +53,7 @@ public class EnablePushNotificationsIQ extends IQ { private final String node; private final HashMap publishOptions; + @SuppressWarnings("this-escape") public EnablePushNotificationsIQ(Jid jid, String node, HashMap publishOptions) { super(ELEMENT, NAMESPACE); this.jid = jid; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/blocking/element/BlockContactsIQ.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/blocking/element/BlockContactsIQ.java index 39cb9525b..79bd2068a 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/blocking/element/BlockContactsIQ.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/blocking/element/BlockContactsIQ.java @@ -51,6 +51,7 @@ public class BlockContactsIQ extends IQ { * * @param jids TODO javadoc me please */ + @SuppressWarnings("this-escape") public BlockContactsIQ(List jids) { super(ELEMENT, NAMESPACE); this.setType(Type.set); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/blocking/element/UnblockContactsIQ.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/blocking/element/UnblockContactsIQ.java index e0a28f722..efba53e3a 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/blocking/element/UnblockContactsIQ.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/blocking/element/UnblockContactsIQ.java @@ -52,6 +52,7 @@ public class UnblockContactsIQ extends IQ { * * @param jids TODO javadoc me please */ + @SuppressWarnings("this-escape") public UnblockContactsIQ(List jids) { super(ELEMENT, NAMESPACE); this.setType(Type.set); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Close.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Close.java index cdd002590..9147cdd72 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Close.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Close.java @@ -36,6 +36,7 @@ public class Close extends IQ { * * @param sessionID unique session ID identifying this In-Band Bytestream */ + @SuppressWarnings("this-escape") public Close(String sessionID) { super(ELEMENT, NAMESPACE); if (sessionID == null || "".equals(sessionID)) { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Data.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Data.java index 54bbaeb80..77ceb9450 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Data.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Data.java @@ -34,6 +34,7 @@ public class Data extends IQ { * * @param data data stanza extension containing the encoded data */ + @SuppressWarnings("this-escape") public Data(DataPacketExtension data) { super(DataPacketExtension.ELEMENT, DataPacketExtension.NAMESPACE); if (data == null) { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Open.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Open.java index 768cf3f20..a2e54bdaf 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Open.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Open.java @@ -54,6 +54,7 @@ public class Open extends IQ { * @param blockSize block size in which the data will be fragmented * @param stanza stanza type used to encapsulate the data */ + @SuppressWarnings("this-escape") public Open(String sessionID, int blockSize, StanzaType stanza) { super(ELEMENT, NAMESPACE); if (sessionID == null || "".equals(sessionID)) { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java index 9d1191b3e..117333095 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java @@ -149,6 +149,7 @@ public class Socks5Proxy { * * @param serverSocket the server socket to use */ + @SuppressWarnings("this-escape") protected Socks5Proxy(ServerSocket serverSocket) { this.serverProcess = new Socks5ServerProcess(); this.serverSocket = serverSocket; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/packet/Bytestream.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/packet/Bytestream.java index 486f89a74..bc049a034 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/packet/Bytestream.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/packet/Bytestream.java @@ -68,6 +68,7 @@ public class Bytestream extends IQ { * @param SID The session ID related to the negotiation. * @see #setSessionID(String) */ + @SuppressWarnings("this-escape") public Bytestream(final String SID) { this(); setSessionID(SID); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandHandler.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandHandler.java index 181fa7c3d..5eb6d6dda 100755 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandHandler.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandHandler.java @@ -57,6 +57,7 @@ public abstract class AdHocCommandHandler extends AbstractAdHocCommand { */ private int currentStage; + @SuppressWarnings("this-escape") public AdHocCommandHandler(String node, String name, String sessionId) { super(node, name); setSessionId(sessionId); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqlast/packet/LastActivity.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqlast/packet/LastActivity.java index 08d3ac686..9a94d0198 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqlast/packet/LastActivity.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqlast/packet/LastActivity.java @@ -45,11 +45,13 @@ public class LastActivity extends IQ { public long lastActivity = -1; public String message; + @SuppressWarnings("this-escape") public LastActivity() { super(ELEMENT, NAMESPACE); setType(IQ.Type.get); } + @SuppressWarnings("this-escape") public LastActivity(Jid to) { this(); setTo(to); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/packet/PrivateDataIQ.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/packet/PrivateDataIQ.java index 6063e040e..5df357e09 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/packet/PrivateDataIQ.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/packet/PrivateDataIQ.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2014 Florian Schmaus + * Copyright 2014-2024 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,11 +27,13 @@ public class PrivateDataIQ extends IQ { private final String getElement; private final String getNamespace; + @SuppressWarnings("this-escape") public PrivateDataIQ(PrivateData privateData) { this(privateData, null, null); setType(Type.set); } + @SuppressWarnings("this-escape") public PrivateDataIQ(String element, String namespace) { this(null, element, namespace); setType(Type.get); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportManager.java index 8c91c8976..ba344ee7c 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportManager.java @@ -30,6 +30,7 @@ public abstract class JingleTransportManager i private final XMPPConnection connection; + @SuppressWarnings("this-escape") public JingleTransportManager(XMPPConnection connection) { this.connection = connection; connection.addConnectionListener(this); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/packet/Ping.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/packet/Ping.java index ac46a76c4..431c1c522 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/packet/Ping.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/packet/Ping.java @@ -1,6 +1,6 @@ /** * - * Copyright 2012-2019 Florian Schmaus + * Copyright 2012-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +32,7 @@ public class Ping extends SimpleIQ { super(ELEMENT, NAMESPACE); } + @SuppressWarnings("this-escape") public Ping(Jid to) { this(); setTo(to); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/packet/PubSub.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/packet/PubSub.java index cf708afe9..138558207 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/packet/PubSub.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/packet/PubSub.java @@ -43,6 +43,7 @@ public class PubSub extends IQ { super(ELEMENT, ns.getXmlns()); } + @SuppressWarnings("this-escape") public PubSub(Jid to, Type type, PubSubNamespace ns) { super(ELEMENT, (ns == null ? PubSubNamespace.basic : ns).getXmlns()); setTo(to); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/time/packet/Time.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/time/packet/Time.java index bb7632210..387a7d390 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/time/packet/Time.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/time/packet/Time.java @@ -1,6 +1,6 @@ /** * - * Copyright 2003-2007 Jive Software, 2014-2021 Florian Schmaus + * Copyright 2003-2007 Jive Software, 2014-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,6 +46,7 @@ public class Time extends IQ implements TimeView { private final String utc; private final String tzo; + @SuppressWarnings("this-escape") public Time(TimeBuilder timeBuilder) { super(timeBuilder, ELEMENT, NAMESPACE); utc = timeBuilder.getUtc(); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/form/FillableForm.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/form/FillableForm.java index 04cee2654..302156c2c 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/form/FillableForm.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/form/FillableForm.java @@ -49,6 +49,7 @@ public class FillableForm extends FilledForm { private final Map filledFields = new HashMap<>(); + @SuppressWarnings("this-escape") public FillableForm(DataForm dataForm) { super(dataForm); if (dataForm.getType() != DataForm.Type.form) { diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/StreamManagementTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/StreamManagementTest.java index 78d075af3..fdbb755c7 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/StreamManagementTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/StreamManagementTest.java @@ -1,6 +1,6 @@ /** * - * Copyright 2015-2020 Florian Schmaus + * Copyright 2015-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,6 +36,7 @@ import org.jxmpp.jid.EntityFullJid; public class StreamManagementTest extends AbstractSmackSpecificLowLevelIntegrationTest { + @SuppressWarnings("this-escape") public StreamManagementTest(SmackIntegrationTestEnvironment environment) throws Exception { super(environment, XMPPTCPConnection.class); XMPPTCPConnection connection = getSpecificUnconnectedConnection(); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatLowLevelIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatLowLevelIntegrationTest.java index c70e61c7e..e13384940 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatLowLevelIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatLowLevelIntegrationTest.java @@ -42,6 +42,7 @@ import org.jxmpp.jid.parts.Resourcepart; @SpecificationReference(document = "XEP-0048", version = "1.2") public class MultiUserChatLowLevelIntegrationTest extends AbstractSmackLowLevelIntegrationTest { + @SuppressWarnings("this-escape") public MultiUserChatLowLevelIntegrationTest(SmackIntegrationTestEnvironment environment) throws Exception { super(environment); AbstractXMPPConnection connection = getConnectedConnection(); diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/JMFInit.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/JMFInit.java index ed86a85de..d41cdcb5f 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/JMFInit.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/JMFInit.java @@ -43,6 +43,7 @@ public class JMFInit extends Frame implements Runnable { private boolean visible = false; + @SuppressWarnings("this-escape") public JMFInit(String[] args, boolean visible) { super("Initializing JMF..."); diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jmf/AudioMediaSession.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jmf/AudioMediaSession.java index 42525c68d..22013df8b 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jmf/AudioMediaSession.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jmf/AudioMediaSession.java @@ -53,6 +53,7 @@ public class AudioMediaSession extends JingleMediaSession { * @param locator media locator * @param jingleSession the jingle session. */ + @SuppressWarnings("this-escape") public AudioMediaSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, String locator, JingleSession jingleSession) { super(payloadType, remote, local, locator == null ? "dsound://" : locator, jingleSession); diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jspeex/AudioMediaSession.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jspeex/AudioMediaSession.java index 78495aa17..162483cd7 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jspeex/AudioMediaSession.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jspeex/AudioMediaSession.java @@ -104,6 +104,7 @@ public class AudioMediaSession extends JingleMediaSession implements MediaSessio * @param locator media locator * @param jingleSession the jingle session. */ + @SuppressWarnings("this-escape") public AudioMediaSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, String locator, JingleSession jingleSession) { super(payloadType, remote, local, locator == null ? "dsound://" : locator, jingleSession); diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/sshare/ScreenShareSession.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/sshare/ScreenShareSession.java index 8a33211e0..2cae0fc22 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/sshare/ScreenShareSession.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/sshare/ScreenShareSession.java @@ -66,6 +66,7 @@ public class ScreenShareSession extends JingleMediaSession { * @param locator media locator * @param jingleSession the jingle session. */ + @SuppressWarnings("this-escape") public ScreenShareSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, final String locator, JingleSession jingleSession) { super(payloadType, remote, local, "Screen", jingleSession); diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/sshare/api/ImageReceiver.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/sshare/api/ImageReceiver.java index c3642d6dd..ed3010be7 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/sshare/api/ImageReceiver.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/sshare/api/ImageReceiver.java @@ -48,6 +48,7 @@ public class ImageReceiver extends Canvas { private int remotePort; private ImageDecoder decoder; + @SuppressWarnings("this-escape") public ImageReceiver(final InetAddress remoteHost, final int remotePort, final int localPort, int width, int height) { tiles = new BufferedImage[width][height]; diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/sshare/api/OctTreeQuantizer.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/sshare/api/OctTreeQuantizer.java index 91cdd7de0..cff438024 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/sshare/api/OctTreeQuantizer.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/sshare/api/OctTreeQuantizer.java @@ -76,7 +76,7 @@ public class OctTreeQuantizer implements Quantizer { private int colors = 0; private final List> colorList; - @SuppressWarnings("JdkObsolete") + @SuppressWarnings({"JdkObsolete", "this-escape"}) public OctTreeQuantizer() { setup(256); colorList = new ArrayList<>(MAX_LEVEL + 1); diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/test/TestMediaSession.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/test/TestMediaSession.java index 1bb4cf746..edfa5a83a 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/test/TestMediaSession.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/test/TestMediaSession.java @@ -37,6 +37,7 @@ public class TestMediaSession extends JingleMediaSession { * @param locator media locator * @param jingleSession the jingle session. */ + @SuppressWarnings("this-escape") public TestMediaSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, final String locator, JingleSession jingleSession) { super(payloadType, remote, local, "Test", jingleSession); diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/FixedResolver.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/FixedResolver.java index d1ea13fad..0a21ac4aa 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/FixedResolver.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/FixedResolver.java @@ -38,6 +38,7 @@ public class FixedResolver extends TransportResolver { * @param ip the IP address. * @param port the port number. */ + @SuppressWarnings("this-escape") public FixedResolver(String ip, int port) { super(); setFixedCandidate(ip, port); diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/ICEResolver.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/ICEResolver.java index f286f5f38..95fce2b6c 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/ICEResolver.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/ICEResolver.java @@ -56,6 +56,7 @@ public class ICEResolver extends TransportResolver { static Map negociatorsMap = new HashMap<>(); // ICENegociator iceNegociator = null; + @SuppressWarnings("this-escape") public ICEResolver(XMPPConnection connection, String server, int port) { super(); this.connection = connection; diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TcpUdpBridgeClient.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TcpUdpBridgeClient.java index 8e3936719..3451b7c1c 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TcpUdpBridgeClient.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TcpUdpBridgeClient.java @@ -45,6 +45,7 @@ public class TcpUdpBridgeClient { private DatagramSocket localUdpSocket; private Socket localTcpSocket; + @SuppressWarnings("this-escape") public TcpUdpBridgeClient(String remoteTcpHost, String remoteUdpHost, int remoteTcpPort, int remoteUdpPort) { this.remoteTcpHost = remoteTcpHost; this.remoteUdpHost = remoteUdpHost; diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TcpUdpBridgeServer.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TcpUdpBridgeServer.java index 2ff8744b5..d5abc6bee 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TcpUdpBridgeServer.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TcpUdpBridgeServer.java @@ -48,6 +48,7 @@ public class TcpUdpBridgeServer { private Socket localTcpSocket; private ServerSocket serverTcpSocket; + @SuppressWarnings("this-escape") public TcpUdpBridgeServer(String remoteTcpHost, String remoteUdpHost, int remoteTcpPort, int remoteUdpPort) { this.remoteTcpHost = remoteTcpHost; this.remoteUdpHost = remoteUdpHost; diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/Jingle.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/Jingle.java index d904f0d34..9ac5270f6 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/Jingle.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/Jingle.java @@ -71,6 +71,7 @@ public class Jingle extends IQ { * @param mi the jingle content info * @param sid the sid. */ + @SuppressWarnings("this-escape") public Jingle(final List contents, final JingleContentInfo mi, final String sid) { this(); @@ -93,6 +94,7 @@ public class Jingle extends IQ { * * @param content a content */ + @SuppressWarnings("this-escape") public Jingle(final JingleContent content) { this(); @@ -112,6 +114,7 @@ public class Jingle extends IQ { * * @param info The content info */ + @SuppressWarnings("this-escape") public Jingle(final JingleContentInfo info) { this(); @@ -131,6 +134,7 @@ public class Jingle extends IQ { * * @param action The action. */ + @SuppressWarnings("this-escape") public Jingle(final JingleActionEnum action) { this(null, null, null); this.action = action; diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/JingleContentDescription.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/JingleContentDescription.java index 3df98e574..fc65a4435 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/JingleContentDescription.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/JingleContentDescription.java @@ -184,6 +184,7 @@ public abstract class JingleContentDescription implements ExtensionElement { * * @param pt the payload type. */ + @SuppressWarnings("this-escape") public Audio(final JinglePayloadType pt) { super(); addJinglePayloadType(pt); diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/JingleContentInfo.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/JingleContentInfo.java index 9d5d7795b..caed15f9d 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/JingleContentInfo.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/JingleContentInfo.java @@ -99,6 +99,7 @@ public class JingleContentInfo implements ExtensionElement { public static final String NAMESPACE = "urn:xmpp:tmp:jingle:apps:rtp"; + @SuppressWarnings("this-escape") public Audio(final ContentInfo mi) { super(mi); setNamespace(NAMESPACE); diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/JingleDescription.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/JingleDescription.java index 4e143f266..f2d2fdf82 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/JingleDescription.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/JingleDescription.java @@ -191,6 +191,7 @@ public abstract class JingleDescription implements ExtensionElement { * * @param pt the payload type. */ + @SuppressWarnings("this-escape") public Audio(final PayloadType pt) { super(); addPayloadType(pt); diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/JingleTransport.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/JingleTransport.java index 40553ea27..1162df9d9 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/JingleTransport.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/JingleTransport.java @@ -55,6 +55,7 @@ public class JingleTransport implements ExtensionElement { * * @param candidate A transport candidate element to add. */ + @SuppressWarnings("this-escape") public JingleTransport(final JingleTransportCandidate candidate) { super(); addCandidate(candidate); @@ -202,6 +203,7 @@ public class JingleTransport implements ExtensionElement { * * @param candidate the jmf transport candidate */ + @SuppressWarnings("this-escape") public JingleTransportCandidate(final TransportCandidate candidate) { super(); setMediaTransport(candidate); @@ -272,6 +274,7 @@ public class JingleTransport implements ExtensionElement { public static class Ice extends JingleTransport { public static final String NAMESPACE = "urn:xmpp:tmp:jingle:transports:ice-udp"; + @SuppressWarnings("this-escape") public Ice() { super(); setNamespace(NAMESPACE); @@ -359,6 +362,7 @@ public class JingleTransport implements ExtensionElement { public static class RawUdp extends JingleTransport { public static final String NAMESPACE = "http://www.xmpp.org/extensions/xep-0177.html#ns"; + @SuppressWarnings("this-escape") public RawUdp() { super(); setNamespace(NAMESPACE); diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/DepartQueuePacket.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/DepartQueuePacket.java index abe8771ca..8917ebe3e 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/DepartQueuePacket.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/DepartQueuePacket.java @@ -53,6 +53,7 @@ public class DepartQueuePacket extends IQ { * @param workgroup the workgroup to depart. * @param user the user to make depart from the queue. */ + @SuppressWarnings("this-escape") public DepartQueuePacket(EntityBareJid workgroup, EntityJid user) { super("depart-queue", "http://jabber.org/protocol/workgroup"); this.user = user; diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/ChatSetting.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/ChatSetting.java index 00a227c61..499d3fac5 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/ChatSetting.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/ChatSetting.java @@ -22,6 +22,7 @@ public class ChatSetting { private String value; private int type; + @SuppressWarnings("this-escape") public ChatSetting(String key, String value, int type) { setKey(key); setValue(value); diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/ChatSettings.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/ChatSettings.java index ddec1a662..8613deb96 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/ChatSettings.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/ChatSettings.java @@ -66,6 +66,7 @@ public class ChatSettings extends IQ { settings = new ArrayList<>(); } + @SuppressWarnings("this-escape") public ChatSettings(String key) { this(); setKey(key); diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java index adb17a07e..ca65956e3 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java @@ -99,6 +99,7 @@ public class Workgroup { * @param connection an XMPP connection which must have already undergone a * successful login. */ + @SuppressWarnings("this-escape") public Workgroup(EntityBareJid workgroupJID, XMPPConnection connection) { // Login must have been done before passing in connection. if (!connection.isAuthenticated()) { diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/xroster/packet/RosterExchange.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/xroster/packet/RosterExchange.java index 291393660..6ee6771f1 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/xroster/packet/RosterExchange.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/xroster/packet/RosterExchange.java @@ -70,6 +70,7 @@ public class RosterExchange implements ExtensionElement { * * @param roster the roster to send to other XMPP entity. */ + @SuppressWarnings("this-escape") public RosterExchange(Roster roster) { // Add all the roster entries to the new RosterExchange for (RosterEntry rosterEntry : roster.getEntries()) { diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java index aef1b27f0..8b4602553 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java @@ -294,6 +294,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { * * @param config the connection configuration. */ + @SuppressWarnings("this-escape") public XMPPTCPConnection(XMPPTCPConnectionConfiguration config) { super(config); this.config = config; From 07d9d694da484821637eb63182e95f4bff2d7450 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 25 Sep 2024 15:28:55 +0200 Subject: [PATCH 136/150] Rename smack-java8(-full) to smack-java11(-full) To denote that Smack now requires at least Java 11 to run. Fixes SMACK-953. --- .github/workflows/ci.yml | 4 ++-- Makefile | 4 ++-- settings.gradle | 4 ++-- .../src/main/java/org/jivesoftware/smackx/package-info.java | 2 +- .../src/main/java/org/jivesoftware/smackx/package-info.java | 2 +- .../src/main/java/org/jivesoftware/smackx/package-info.java | 2 +- .../src/main/java/org/jivesoftware/smackx/package-info.java | 2 +- smack-integration-test/build.gradle | 2 +- .../src/main/java/org/jivesoftware/smackx/package-info.java | 2 +- {smack-java8-full => smack-java11-full}/build.gradle | 2 +- .../javadoc/org/jivesoftware/smack/full/doc-files/.gitignore | 0 .../smack/full/ModularXmppClientToServerConnectionTool.java | 0 .../main/java/org/jivesoftware/smack/full/package-info.java | 0 .../main/java/org/jivesoftware/smackx/SmackExtensions.java | 0 .../src/main/java/org/jivesoftware/smackx/package-info.java | 0 .../smack/full/ExtensionElementQNameDeclaredTest.java | 0 .../ModularXmppClientToServerConnectionStateGraphTest.java | 0 .../src/test/resources/state-graph.dot | 0 {smack-java8 => smack-java11}/build.gradle | 0 .../org/jivesoftware/smack/java7/Java7SmackInitializer.java | 0 .../org/jivesoftware/smack/java7/XmppHostnameVerifier.java | 0 .../main/java/org/jivesoftware/smack/java7/package-info.java | 0 .../smack/util/stringencoder/java7/Java7Base64Encoder.java | 0 .../util/stringencoder/java7/Java7Base64UrlSafeEncoder.java | 0 .../smack/util/stringencoder/java7/package-info.java | 0 .../jivesoftware/smack/util/stringencoder/package-info.java | 0 .../src/main/java/org/jivesoftware/smackx/package-info.java | 2 +- .../src/main/java/org/jivesoftware/smackx/package-info.java | 2 +- 28 files changed, 15 insertions(+), 15 deletions(-) rename {smack-java8-full => smack-java11-full}/build.gradle (98%) rename {smack-java8-full => smack-java11-full}/src/javadoc/org/jivesoftware/smack/full/doc-files/.gitignore (100%) rename {smack-java8-full => smack-java11-full}/src/main/java/org/jivesoftware/smack/full/ModularXmppClientToServerConnectionTool.java (100%) rename {smack-java8-full => smack-java11-full}/src/main/java/org/jivesoftware/smack/full/package-info.java (100%) rename {smack-java8-full => smack-java11-full}/src/main/java/org/jivesoftware/smackx/SmackExtensions.java (100%) rename {smack-java8-full => smack-java11-full}/src/main/java/org/jivesoftware/smackx/package-info.java (100%) rename {smack-java8-full => smack-java11-full}/src/test/java/org/jivesoftware/smack/full/ExtensionElementQNameDeclaredTest.java (100%) rename {smack-java8-full => smack-java11-full}/src/test/java/org/jivesoftware/smack/full/ModularXmppClientToServerConnectionStateGraphTest.java (100%) rename {smack-java8-full => smack-java11-full}/src/test/resources/state-graph.dot (100%) rename {smack-java8 => smack-java11}/build.gradle (100%) rename {smack-java8 => smack-java11}/src/main/java/org/jivesoftware/smack/java7/Java7SmackInitializer.java (100%) rename {smack-java8 => smack-java11}/src/main/java/org/jivesoftware/smack/java7/XmppHostnameVerifier.java (100%) rename {smack-java8 => smack-java11}/src/main/java/org/jivesoftware/smack/java7/package-info.java (100%) rename {smack-java8 => smack-java11}/src/main/java/org/jivesoftware/smack/util/stringencoder/java7/Java7Base64Encoder.java (100%) rename {smack-java8 => smack-java11}/src/main/java/org/jivesoftware/smack/util/stringencoder/java7/Java7Base64UrlSafeEncoder.java (100%) rename {smack-java8 => smack-java11}/src/main/java/org/jivesoftware/smack/util/stringencoder/java7/package-info.java (100%) rename {smack-java8 => smack-java11}/src/main/java/org/jivesoftware/smack/util/stringencoder/package-info.java (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b1019ea4b..c9e8795af 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -95,8 +95,8 @@ jobs: else echo COVERALLS_REPO_TOKEN is not empty fi - ./gradlew smack-java8-full:testCodeCoverageReport - ./gradlew smack-java8-full:coveralls + ./gradlew smack-java11-full:testCodeCoverageReport + ./gradlew smack-java11-full:coveralls # Upload build artifacts - name: Upload build artifacts diff --git a/Makefile b/Makefile index 0621bf85f..4689ef8af 100644 --- a/Makefile +++ b/Makefile @@ -5,8 +5,8 @@ all: check jacocoRootReport javadocAll sinttest .PHONY: codecov codecov: - $(GRADLE) smack-java8-full:testCodeCoverageReport - echo "Report available at smack-java8-full/build/reports/jacoco/testCodeCoverageReport/html/index.html" + $(GRADLE) smack-java11-full:testCodeCoverageReport + echo "Report available at smack-java11-full/build/reports/jacoco/testCodeCoverageReport/html/index.html" .PHONY: check check: diff --git a/settings.gradle b/settings.gradle index 2ed68cff5..d433b95d3 100644 --- a/settings.gradle +++ b/settings.gradle @@ -27,8 +27,8 @@ include 'smack-core', 'smack-bosh', 'smack-android', 'smack-android-extensions', - 'smack-java8', - 'smack-java8-full', + 'smack-java11', + 'smack-java11-full', 'smack-integration-test', 'smack-omemo', 'smack-omemo-signal', diff --git a/smack-android-extensions/src/main/java/org/jivesoftware/smackx/package-info.java b/smack-android-extensions/src/main/java/org/jivesoftware/smackx/package-info.java index 7ebe86244..bce3b6064 120000 --- a/smack-android-extensions/src/main/java/org/jivesoftware/smackx/package-info.java +++ b/smack-android-extensions/src/main/java/org/jivesoftware/smackx/package-info.java @@ -1 +1 @@ -../../../../../../../smack-java8-full/src/main/java/org/jivesoftware/smackx/package-info.java \ No newline at end of file +../../../../../../../smack-java11-full/src/main/java/org/jivesoftware/smackx/package-info.java \ No newline at end of file diff --git a/smack-android/src/main/java/org/jivesoftware/smackx/package-info.java b/smack-android/src/main/java/org/jivesoftware/smackx/package-info.java index 7ebe86244..bce3b6064 120000 --- a/smack-android/src/main/java/org/jivesoftware/smackx/package-info.java +++ b/smack-android/src/main/java/org/jivesoftware/smackx/package-info.java @@ -1 +1 @@ -../../../../../../../smack-java8-full/src/main/java/org/jivesoftware/smackx/package-info.java \ No newline at end of file +../../../../../../../smack-java11-full/src/main/java/org/jivesoftware/smackx/package-info.java \ No newline at end of file diff --git a/smack-debug-slf4j/src/main/java/org/jivesoftware/smackx/package-info.java b/smack-debug-slf4j/src/main/java/org/jivesoftware/smackx/package-info.java index 7ebe86244..bce3b6064 120000 --- a/smack-debug-slf4j/src/main/java/org/jivesoftware/smackx/package-info.java +++ b/smack-debug-slf4j/src/main/java/org/jivesoftware/smackx/package-info.java @@ -1 +1 @@ -../../../../../../../smack-java8-full/src/main/java/org/jivesoftware/smackx/package-info.java \ No newline at end of file +../../../../../../../smack-java11-full/src/main/java/org/jivesoftware/smackx/package-info.java \ No newline at end of file diff --git a/smack-debug/src/main/java/org/jivesoftware/smackx/package-info.java b/smack-debug/src/main/java/org/jivesoftware/smackx/package-info.java index 7ebe86244..bce3b6064 120000 --- a/smack-debug/src/main/java/org/jivesoftware/smackx/package-info.java +++ b/smack-debug/src/main/java/org/jivesoftware/smackx/package-info.java @@ -1 +1 @@ -../../../../../../../smack-java8-full/src/main/java/org/jivesoftware/smackx/package-info.java \ No newline at end of file +../../../../../../../smack-java11-full/src/main/java/org/jivesoftware/smackx/package-info.java \ No newline at end of file diff --git a/smack-integration-test/build.gradle b/smack-integration-test/build.gradle index 479ee0036..ede353266 100644 --- a/smack-integration-test/build.gradle +++ b/smack-integration-test/build.gradle @@ -12,7 +12,7 @@ application { } dependencies { - api project(':smack-java8-full') + api project(':smack-java11-full') api project(':smack-resolver-dnsjava') implementation project(':smack-websocket-java11') implementation "com.google.guava:guava:${guavaVersion}" diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/package-info.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/package-info.java index 7ebe86244..bce3b6064 120000 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/package-info.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/package-info.java @@ -1 +1 @@ -../../../../../../../smack-java8-full/src/main/java/org/jivesoftware/smackx/package-info.java \ No newline at end of file +../../../../../../../smack-java11-full/src/main/java/org/jivesoftware/smackx/package-info.java \ No newline at end of file diff --git a/smack-java8-full/build.gradle b/smack-java11-full/build.gradle similarity index 98% rename from smack-java8-full/build.gradle rename to smack-java11-full/build.gradle index 61a4e00e0..4f4bf0652 100644 --- a/smack-java8-full/build.gradle +++ b/smack-java11-full/build.gradle @@ -10,7 +10,7 @@ dependencies { api project(':smack-debug') api project(':smack-experimental') api project(':smack-extensions') - api project(':smack-java8') + api project(':smack-java11') api project(':smack-legacy') api project(':smack-omemo') api project(':smack-openpgp') diff --git a/smack-java8-full/src/javadoc/org/jivesoftware/smack/full/doc-files/.gitignore b/smack-java11-full/src/javadoc/org/jivesoftware/smack/full/doc-files/.gitignore similarity index 100% rename from smack-java8-full/src/javadoc/org/jivesoftware/smack/full/doc-files/.gitignore rename to smack-java11-full/src/javadoc/org/jivesoftware/smack/full/doc-files/.gitignore diff --git a/smack-java8-full/src/main/java/org/jivesoftware/smack/full/ModularXmppClientToServerConnectionTool.java b/smack-java11-full/src/main/java/org/jivesoftware/smack/full/ModularXmppClientToServerConnectionTool.java similarity index 100% rename from smack-java8-full/src/main/java/org/jivesoftware/smack/full/ModularXmppClientToServerConnectionTool.java rename to smack-java11-full/src/main/java/org/jivesoftware/smack/full/ModularXmppClientToServerConnectionTool.java diff --git a/smack-java8-full/src/main/java/org/jivesoftware/smack/full/package-info.java b/smack-java11-full/src/main/java/org/jivesoftware/smack/full/package-info.java similarity index 100% rename from smack-java8-full/src/main/java/org/jivesoftware/smack/full/package-info.java rename to smack-java11-full/src/main/java/org/jivesoftware/smack/full/package-info.java diff --git a/smack-java8-full/src/main/java/org/jivesoftware/smackx/SmackExtensions.java b/smack-java11-full/src/main/java/org/jivesoftware/smackx/SmackExtensions.java similarity index 100% rename from smack-java8-full/src/main/java/org/jivesoftware/smackx/SmackExtensions.java rename to smack-java11-full/src/main/java/org/jivesoftware/smackx/SmackExtensions.java diff --git a/smack-java8-full/src/main/java/org/jivesoftware/smackx/package-info.java b/smack-java11-full/src/main/java/org/jivesoftware/smackx/package-info.java similarity index 100% rename from smack-java8-full/src/main/java/org/jivesoftware/smackx/package-info.java rename to smack-java11-full/src/main/java/org/jivesoftware/smackx/package-info.java diff --git a/smack-java8-full/src/test/java/org/jivesoftware/smack/full/ExtensionElementQNameDeclaredTest.java b/smack-java11-full/src/test/java/org/jivesoftware/smack/full/ExtensionElementQNameDeclaredTest.java similarity index 100% rename from smack-java8-full/src/test/java/org/jivesoftware/smack/full/ExtensionElementQNameDeclaredTest.java rename to smack-java11-full/src/test/java/org/jivesoftware/smack/full/ExtensionElementQNameDeclaredTest.java diff --git a/smack-java8-full/src/test/java/org/jivesoftware/smack/full/ModularXmppClientToServerConnectionStateGraphTest.java b/smack-java11-full/src/test/java/org/jivesoftware/smack/full/ModularXmppClientToServerConnectionStateGraphTest.java similarity index 100% rename from smack-java8-full/src/test/java/org/jivesoftware/smack/full/ModularXmppClientToServerConnectionStateGraphTest.java rename to smack-java11-full/src/test/java/org/jivesoftware/smack/full/ModularXmppClientToServerConnectionStateGraphTest.java diff --git a/smack-java8-full/src/test/resources/state-graph.dot b/smack-java11-full/src/test/resources/state-graph.dot similarity index 100% rename from smack-java8-full/src/test/resources/state-graph.dot rename to smack-java11-full/src/test/resources/state-graph.dot diff --git a/smack-java8/build.gradle b/smack-java11/build.gradle similarity index 100% rename from smack-java8/build.gradle rename to smack-java11/build.gradle diff --git a/smack-java8/src/main/java/org/jivesoftware/smack/java7/Java7SmackInitializer.java b/smack-java11/src/main/java/org/jivesoftware/smack/java7/Java7SmackInitializer.java similarity index 100% rename from smack-java8/src/main/java/org/jivesoftware/smack/java7/Java7SmackInitializer.java rename to smack-java11/src/main/java/org/jivesoftware/smack/java7/Java7SmackInitializer.java diff --git a/smack-java8/src/main/java/org/jivesoftware/smack/java7/XmppHostnameVerifier.java b/smack-java11/src/main/java/org/jivesoftware/smack/java7/XmppHostnameVerifier.java similarity index 100% rename from smack-java8/src/main/java/org/jivesoftware/smack/java7/XmppHostnameVerifier.java rename to smack-java11/src/main/java/org/jivesoftware/smack/java7/XmppHostnameVerifier.java diff --git a/smack-java8/src/main/java/org/jivesoftware/smack/java7/package-info.java b/smack-java11/src/main/java/org/jivesoftware/smack/java7/package-info.java similarity index 100% rename from smack-java8/src/main/java/org/jivesoftware/smack/java7/package-info.java rename to smack-java11/src/main/java/org/jivesoftware/smack/java7/package-info.java diff --git a/smack-java8/src/main/java/org/jivesoftware/smack/util/stringencoder/java7/Java7Base64Encoder.java b/smack-java11/src/main/java/org/jivesoftware/smack/util/stringencoder/java7/Java7Base64Encoder.java similarity index 100% rename from smack-java8/src/main/java/org/jivesoftware/smack/util/stringencoder/java7/Java7Base64Encoder.java rename to smack-java11/src/main/java/org/jivesoftware/smack/util/stringencoder/java7/Java7Base64Encoder.java diff --git a/smack-java8/src/main/java/org/jivesoftware/smack/util/stringencoder/java7/Java7Base64UrlSafeEncoder.java b/smack-java11/src/main/java/org/jivesoftware/smack/util/stringencoder/java7/Java7Base64UrlSafeEncoder.java similarity index 100% rename from smack-java8/src/main/java/org/jivesoftware/smack/util/stringencoder/java7/Java7Base64UrlSafeEncoder.java rename to smack-java11/src/main/java/org/jivesoftware/smack/util/stringencoder/java7/Java7Base64UrlSafeEncoder.java diff --git a/smack-java8/src/main/java/org/jivesoftware/smack/util/stringencoder/java7/package-info.java b/smack-java11/src/main/java/org/jivesoftware/smack/util/stringencoder/java7/package-info.java similarity index 100% rename from smack-java8/src/main/java/org/jivesoftware/smack/util/stringencoder/java7/package-info.java rename to smack-java11/src/main/java/org/jivesoftware/smack/util/stringencoder/java7/package-info.java diff --git a/smack-java8/src/main/java/org/jivesoftware/smack/util/stringencoder/package-info.java b/smack-java11/src/main/java/org/jivesoftware/smack/util/stringencoder/package-info.java similarity index 100% rename from smack-java8/src/main/java/org/jivesoftware/smack/util/stringencoder/package-info.java rename to smack-java11/src/main/java/org/jivesoftware/smack/util/stringencoder/package-info.java diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/package-info.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/package-info.java index 7ebe86244..bce3b6064 120000 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/package-info.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/package-info.java @@ -1 +1 @@ -../../../../../../../smack-java8-full/src/main/java/org/jivesoftware/smackx/package-info.java \ No newline at end of file +../../../../../../../smack-java11-full/src/main/java/org/jivesoftware/smackx/package-info.java \ No newline at end of file diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/package-info.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/package-info.java index 7ebe86244..bce3b6064 120000 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/package-info.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/package-info.java @@ -1 +1 @@ -../../../../../../../smack-java8-full/src/main/java/org/jivesoftware/smackx/package-info.java \ No newline at end of file +../../../../../../../smack-java11-full/src/main/java/org/jivesoftware/smackx/package-info.java \ No newline at end of file From d217c32e7241422006f995100d9ccec209ee21d7 Mon Sep 17 00:00:00 2001 From: akrherz Date: Wed, 25 Sep 2024 12:51:02 -0500 Subject: [PATCH 137/150] [build] Downgrade bnd gradle plugin to 6.4.0 7.0.0 requires Java 17 --- build-logic/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-logic/build.gradle b/build-logic/build.gradle index 795d644bd..c0b172601 100644 --- a/build-logic/build.gradle +++ b/build-logic/build.gradle @@ -7,7 +7,7 @@ repositories { } dependencies { - implementation "biz.aQute.bnd:biz.aQute.bnd.gradle:7.0.0" + implementation "biz.aQute.bnd:biz.aQute.bnd.gradle:6.4.0" implementation "io.freefair.gradle:maven-plugin:8.10" // for io.freefair.agregate-javadoc implementation "me.champeau.jmh:jmh-gradle-plugin:0.7.2" implementation "net.ltgt.gradle:gradle-errorprone-plugin:4.0.1" From beacb5eb8e958a5a8c855ed13fa2480eaa9425f2 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 25 Sep 2024 21:32:17 +0200 Subject: [PATCH 138/150] [build] Bump error prone from 2.9.0 to 2.32.0 --- ...ltime.smack.java-common-conventions.gradle | 3 +- .../android/ServerPingWithAlarmManager.java | 3 +- .../smack/SmackInitialization.java | 4 +- .../ModularXmppClientToServerConnection.java | 21 ++++- .../CompressionModuleDescriptor.java | 4 +- .../smack/fsm/StateDescriptorGraph.java | 4 +- ...stantStreamResumptionModuleDescriptor.java | 2 + .../proxy/HTTPProxySocketConnection.java | 3 +- .../smack/util/CollectionUtil.java | 1 + .../org/jivesoftware/smack/util/Pair.java | 4 +- .../jivesoftware/smack/util/SecurityUtil.java | 5 +- .../jivesoftware/smack/util/StringUtils.java | 4 +- .../smack/examples/OmemoClient.java | 2 +- .../muclight/MUCLightRoomConfiguration.java | 8 +- .../smackx/muclight/MUCLightRoomInfo.java | 8 +- .../smackx/muclight/MultiUserChatLight.java | 15 ++-- .../muclight/MultiUserChatLightManager.java | 8 +- .../element/MUCLightAffiliationsIQ.java | 7 +- .../muclight/element/MUCLightBlockingIQ.java | 13 ++- .../element/MUCLightChangeAffiliationsIQ.java | 7 +- .../muclight/element/MUCLightCreateIQ.java | 7 +- .../muclight/element/MUCLightElements.java | 17 ++-- .../muclight/element/MUCLightInfoIQ.java | 8 +- .../element/MUCLightSetConfigsIQ.java | 7 +- .../provider/MUCLightBlockingIQProvider.java | 7 +- .../provider/MUCLightInfoIQProvider.java | 9 ++- .../PushNotificationsManager.java | 3 +- .../element/EnablePushNotificationsIQ.java | 7 +- ...CLightAffiliationsChangeExtensionTest.java | 8 +- .../MUCLightChangeAffiliationsIQTest.java | 5 +- .../smackx/muclight/MUCLightCreateIQTest.java | 4 +- .../muclight/MUCLightGetAffiliationsTest.java | 4 +- .../muclight/MUCLightGetConfigsTest.java | 4 +- .../smackx/commands/AdHocCommandManager.java | 6 +- .../JivePropertiesExtensionProvider.java | 2 +- .../smackx/privacy/PrivacyListManager.java | 2 - .../jivesoftware/smackx/xdata/FormField.java | 2 +- .../socks5/Socks5ByteStreamManagerTest.java | 16 ++-- .../smack/inttest/Configuration.java | 3 +- .../HttpFileUploadIntegrationTest.java | 2 +- .../smackx/omemo/OmemoManagerSetupHelper.java | 16 ++-- .../SmackIntegrationTestFrameWorkTest.java | 10 +-- .../smackx/jingleold/mediaimpl/JMFInit.java | 2 +- .../mediaimpl/jspeex/AudioMediaSession.java | 4 +- .../smackx/jingleold/nat/STUNResolver.java | 7 +- .../jingleold/nat/TransportCandidate.java | 81 +++++++------------ .../jingleold/nat/TransportNegotiator.java | 8 +- .../jingleold/nat/TransportResolver.java | 2 +- .../packet/JingleContentDescription.java | 4 +- .../smackx/workgroup/agent/AgentSession.java | 8 +- .../smackx/workgroup/user/Workgroup.java | 2 +- .../omemo/signal/SignalOmemoKeyUtil.java | 1 + .../smackx/omemo/CachingOmemoStore.java | 9 ++- .../smackx/omemo/FileBasedOmemoStore.java | 3 + .../smackx/omemo/OmemoManager.java | 5 +- .../smackx/omemo/OmemoMessage.java | 7 +- .../smackx/omemo/OmemoService.java | 3 +- .../jivesoftware/smackx/omemo/OmemoStore.java | 13 +-- .../omemo/element/OmemoBundleElement.java | 20 ++--- .../element/OmemoBundleElement_VAxolotl.java | 6 +- .../omemo/element/OmemoHeaderElement.java | 2 +- .../CannotEstablishOmemoSessionException.java | 23 +++--- .../smackx/omemo/util/OmemoKeyUtil.java | 10 ++- .../smackx/omemo/OmemoKeyUtilTest.java | 4 +- .../smackx/omemo/OmemoStoreTest.java | 6 +- .../ox/element/PublicKeysListElement.java | 7 +- .../smack/util/dns/javax/JavaxResolver.java | 1 + .../smack/tcp/XMPPTCPConnection.java | 3 +- .../tcp/XmppTcpTransportModuleDescriptor.java | 4 +- 69 files changed, 265 insertions(+), 255 deletions(-) diff --git a/build-logic/src/main/groovy/org.igniterealtime.smack.java-common-conventions.gradle b/build-logic/src/main/groovy/org.igniterealtime.smack.java-common-conventions.gradle index e6a9ecbbf..aedba32fb 100644 --- a/build-logic/src/main/groovy/org.igniterealtime.smack.java-common-conventions.gradle +++ b/build-logic/src/main/groovy/org.igniterealtime.smack.java-common-conventions.gradle @@ -142,8 +142,7 @@ dependencies { testImplementation 'com.jamesmurty.utils:java-xmlbuilder:1.2' - errorprone 'com.google.errorprone:error_prone_core:2.9.0' - errorproneJavac('com.google.errorprone:javac:9+181-r4173-1') + errorprone 'com.google.errorprone:error_prone_core:2.32.0' } test { diff --git a/smack-android-extensions/src/main/java/org/jivesoftware/smackx/ping/android/ServerPingWithAlarmManager.java b/smack-android-extensions/src/main/java/org/jivesoftware/smackx/ping/android/ServerPingWithAlarmManager.java index 3d217efcb..f4a93d150 100644 --- a/smack-android-extensions/src/main/java/org/jivesoftware/smackx/ping/android/ServerPingWithAlarmManager.java +++ b/smack-android-extensions/src/main/java/org/jivesoftware/smackx/ping/android/ServerPingWithAlarmManager.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2014-2021 Florian Schmaus + * Copyright © 2014-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -121,6 +121,7 @@ public final class ServerPingWithAlarmManager extends Manager { private static final BroadcastReceiver ALARM_BROADCAST_RECEIVER = new BroadcastReceiver() { @Override + @SuppressWarnings("LockOnNonEnclosingClassLiteral") public void onReceive(Context context, Intent intent) { LOGGER.fine("Ping Alarm broadcast received"); Set> managers; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/SmackInitialization.java b/smack-core/src/main/java/org/jivesoftware/smack/SmackInitialization.java index 2a5b79c6a..82098094f 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SmackInitialization.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SmackInitialization.java @@ -1,6 +1,6 @@ /** * - * Copyright 2003-2007 Jive Software, 2014-2020 Florian Schmaus + * Copyright 2003-2007 Jive Software, 2014-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,7 +63,7 @@ public final class SmackInitialization { private static final Logger LOGGER = Logger.getLogger(SmackInitialization.class.getName()); - /** + /* * Loads the configuration from the smack-config.xml and system properties file. *

      * So far this means that: diff --git a/smack-core/src/main/java/org/jivesoftware/smack/c2s/ModularXmppClientToServerConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/c2s/ModularXmppClientToServerConnection.java index 5f060311a..ca3de8190 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/c2s/ModularXmppClientToServerConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/c2s/ModularXmppClientToServerConnection.java @@ -667,7 +667,8 @@ public final class ModularXmppClientToServerConnection extends AbstractXMPPConne } private final class DisconnectedState extends State { - + // Invoked via reflection. + @SuppressWarnings("UnusedMethod") private DisconnectedState(StateDescriptor stateDescriptor, ModularXmppClientToServerConnectionInternal connectionInternal) { super(stateDescriptor, connectionInternal); @@ -708,6 +709,8 @@ public final class ModularXmppClientToServerConnection extends AbstractXMPPConne private final class LookupRemoteConnectionEndpointsState extends State { boolean outgoingElementsQueueWasShutdown; + // Invoked via reflection. + @SuppressWarnings("UnusedMethod") private LookupRemoteConnectionEndpointsState(StateDescriptor stateDescriptor, ModularXmppClientToServerConnectionInternal connectionInternal) { super(stateDescriptor, connectionInternal); @@ -818,6 +821,8 @@ public final class ModularXmppClientToServerConnection extends AbstractXMPPConne } private final class ConnectedButUnauthenticatedState extends State { + // Invoked via reflection. + @SuppressWarnings("UnusedMethod") private ConnectedButUnauthenticatedState(StateDescriptor stateDescriptor, ModularXmppClientToServerConnectionInternal connectionInternal) { super(stateDescriptor, connectionInternal); @@ -850,6 +855,8 @@ public final class ModularXmppClientToServerConnection extends AbstractXMPPConne } private final class SaslAuthenticationState extends State { + // Invoked via reflection. + @SuppressWarnings("UnusedMethod") private SaslAuthenticationState(StateDescriptor stateDescriptor, ModularXmppClientToServerConnectionInternal connectionInternal) { super(stateDescriptor, connectionInternal); @@ -893,6 +900,8 @@ public final class ModularXmppClientToServerConnection extends AbstractXMPPConne } public static final class ResourceBindingStateDescriptor extends StateDescriptor { + // Invoked via reflection. + @SuppressWarnings("UnusedMethod") private ResourceBindingStateDescriptor() { super(ResourceBindingState.class, "RFC 6120 § 7"); addSuccessor(AuthenticatedAndResourceBoundStateDescriptor.class); @@ -900,6 +909,8 @@ public final class ModularXmppClientToServerConnection extends AbstractXMPPConne } private final class ResourceBindingState extends State { + // Invoked via reflection. + @SuppressWarnings("UnusedMethod") private ResourceBindingState(StateDescriptor stateDescriptor, ModularXmppClientToServerConnectionInternal connectionInternal) { super(stateDescriptor, connectionInternal); @@ -955,6 +966,8 @@ public final class ModularXmppClientToServerConnection extends AbstractXMPPConne } private final class AuthenticatedAndResourceBoundState extends State { + // Invoked via reflection. + @SuppressWarnings("UnusedMethod") private AuthenticatedAndResourceBoundState(StateDescriptor stateDescriptor, ModularXmppClientToServerConnectionInternal connectionInternal) { super(stateDescriptor, connectionInternal); @@ -995,6 +1008,8 @@ public final class ModularXmppClientToServerConnection extends AbstractXMPPConne } private final class ShutdownState extends State { + // Invoked via reflection. + @SuppressWarnings("UnusedMethod") private ShutdownState(StateDescriptor stateDescriptor, ModularXmppClientToServerConnectionInternal connectionInternal) { super(stateDescriptor, connectionInternal); @@ -1057,6 +1072,8 @@ public final class ModularXmppClientToServerConnection extends AbstractXMPPConne } private static final class InstantShutdownState extends NoOpState { + // Invoked via reflection. + @SuppressWarnings("UnusedMethod") private InstantShutdownState(ModularXmppClientToServerConnection connection, StateDescriptor stateDescriptor, ModularXmppClientToServerConnectionInternal connectionInternal) { super(connection, stateDescriptor, connectionInternal); @@ -1078,6 +1095,8 @@ public final class ModularXmppClientToServerConnection extends AbstractXMPPConne } private final class CloseConnectionState extends State { + // Invoked via reflection. + @SuppressWarnings("UnusedMethod") private CloseConnectionState(StateDescriptor stateDescriptor, ModularXmppClientToServerConnectionInternal connectionInternal) { super(stateDescriptor, connectionInternal); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/compression/CompressionModuleDescriptor.java b/smack-core/src/main/java/org/jivesoftware/smack/compression/CompressionModuleDescriptor.java index 3cf43ee79..4fa0e6045 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/compression/CompressionModuleDescriptor.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/compression/CompressionModuleDescriptor.java @@ -1,6 +1,6 @@ /** * - * Copyright 2018-2020 Florian Schmaus + * Copyright 2018-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,6 +41,8 @@ public class CompressionModuleDescriptor extends ModularXmppClientToServerConnec public static final class Builder extends ModularXmppClientToServerConnectionModuleDescriptor.Builder { + // Invoked via reflection. + @SuppressWarnings("UnusedMethod") private Builder(ModularXmppClientToServerConnectionConfiguration.Builder connectionConfigurationBuilder) { super(connectionConfigurationBuilder); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/fsm/StateDescriptorGraph.java b/smack-core/src/main/java/org/jivesoftware/smack/fsm/StateDescriptorGraph.java index 224e1fab0..45d23bb36 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/fsm/StateDescriptorGraph.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/fsm/StateDescriptorGraph.java @@ -1,6 +1,6 @@ /** * - * Copyright 2018-2021 Florian Schmaus + * Copyright 2018-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -368,7 +368,7 @@ public class StateDescriptorGraph { } } - public static void stateDescriptorGraphToDot(Collection> vertexes, + public static void stateDescriptorGraphToDot(Collection> vertexes, PrintWriter dotOut, boolean breakStateName) { dotOut.append("digraph {\n"); dfs(vertexes, diff --git a/smack-core/src/main/java/org/jivesoftware/smack/isr/InstantStreamResumptionModuleDescriptor.java b/smack-core/src/main/java/org/jivesoftware/smack/isr/InstantStreamResumptionModuleDescriptor.java index d26703eec..3e8171076 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/isr/InstantStreamResumptionModuleDescriptor.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/isr/InstantStreamResumptionModuleDescriptor.java @@ -41,6 +41,8 @@ public class InstantStreamResumptionModuleDescriptor extends ModularXmppClientTo public static final class Builder extends ModularXmppClientToServerConnectionModuleDescriptor.Builder { + // Unfinished implementation. + @SuppressWarnings("UnusedMethod") private Builder(ModularXmppClientToServerConnectionConfiguration.Builder connectionConfigurationBuilder) { super(connectionConfigurationBuilder); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/proxy/HTTPProxySocketConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/proxy/HTTPProxySocketConnection.java index 549406423..bdf0cf390 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/proxy/HTTPProxySocketConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/proxy/HTTPProxySocketConnection.java @@ -23,6 +23,7 @@ import java.io.StringReader; import java.net.HttpURLConnection; import java.net.InetSocketAddress; import java.net.Socket; +import java.nio.charset.StandardCharsets; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -58,7 +59,7 @@ class HTTPProxySocketConnection implements ProxySocketConnection { proxyLine = "\r\nProxy-Authorization: Basic " + Base64.encode(username + ":" + password); } socket.getOutputStream().write((hostport + " HTTP/1.1\r\nHost: " - + host + ":" + port + proxyLine + "\r\n\r\n").getBytes("UTF-8")); + + host + ":" + port + proxyLine + "\r\n\r\n").getBytes(StandardCharsets.UTF_8)); InputStream in = socket.getInputStream(); StringBuilder got = new StringBuilder(100); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/CollectionUtil.java b/smack-core/src/main/java/org/jivesoftware/smack/util/CollectionUtil.java index 408e00bfd..c3566c6c0 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/CollectionUtil.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/CollectionUtil.java @@ -55,6 +55,7 @@ public class CollectionUtil { boolean test(T t); } + @SuppressWarnings("NonApiType") public static ArrayList newListWith(Collection collection) { if (collection == null) { return null; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/Pair.java b/smack-core/src/main/java/org/jivesoftware/smack/util/Pair.java index 76ebc1dc5..13e65e881 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/Pair.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/Pair.java @@ -26,12 +26,12 @@ public final class Pair { this.second = second; } - public static Pair create(F first, S second) { + public static Pair create(F first, S second) { return new Pair<>(first, second); } @SuppressWarnings("ReturnValueIgnored") - public static Pair createAndInitHashCode(F first, S second) { + public static Pair createAndInitHashCode(F first, S second) { Pair pair = new Pair<>(first, second); pair.hashCode(); return pair; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/SecurityUtil.java b/smack-core/src/main/java/org/jivesoftware/smack/util/SecurityUtil.java index 3521279df..c796ab23e 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/SecurityUtil.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/SecurityUtil.java @@ -1,6 +1,6 @@ /** * - * Copyright 2019 Florian Schmaus. + * Copyright 2019-2024 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ public class SecurityUtil { private static final LruCache, Void> INSERTED_PROVIDERS_CACHE = new LruCache<>(8); + @SuppressWarnings("LockOnNonEnclosingClassLiteral") public static void ensureProviderAtFirstPosition(Class providerClass) { if (INSERTED_PROVIDERS_CACHE.containsKey(providerClass)) { return; @@ -41,7 +42,7 @@ public class SecurityUtil { String providerName = provider.getName(); - int installedPosition ; + int installedPosition; synchronized (Security.class) { Security.removeProvider(providerName); installedPosition = Security.insertProviderAt(provider, 1); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java index ffadbda00..83c9f40bb 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java @@ -464,7 +464,7 @@ public class StringUtils { appendTo(collection, ", ", sb); } - public static void appendTo(Collection collection, StringBuilder sb, + public static void appendTo(Collection collection, StringBuilder sb, Consumer appendFunction) { appendTo(collection, ", ", sb, appendFunction); } @@ -473,7 +473,7 @@ public class StringUtils { appendTo(collection, delimiter, sb, o -> sb.append(o)); } - public static void appendTo(Collection collection, String delimiter, StringBuilder sb, + public static void appendTo(Collection collection, String delimiter, StringBuilder sb, Consumer appendFunction) { for (Iterator it = collection.iterator(); it.hasNext();) { O cs = it.next(); diff --git a/smack-examples/src/main/java/org/igniterealtime/smack/examples/OmemoClient.java b/smack-examples/src/main/java/org/igniterealtime/smack/examples/OmemoClient.java index b247c77b2..9c8652107 100644 --- a/smack-examples/src/main/java/org/igniterealtime/smack/examples/OmemoClient.java +++ b/smack-examples/src/main/java/org/igniterealtime/smack/examples/OmemoClient.java @@ -185,7 +185,7 @@ public class OmemoClient { BareJid contact = JidCreate.bareFrom(com[1]); - HashMap devices; + Map devices; try { devices = omemoManager.getActiveFingerprints(contact); } catch (CorruptedOmemoKeyException | CannotEstablishOmemoSessionException | SmackException.NoResponseException e) { diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MUCLightRoomConfiguration.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MUCLightRoomConfiguration.java index aab822087..7f0595871 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MUCLightRoomConfiguration.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MUCLightRoomConfiguration.java @@ -16,7 +16,7 @@ */ package org.jivesoftware.smackx.muclight; -import java.util.HashMap; +import java.util.Map; /** * MUC Light room configuration class. @@ -28,7 +28,7 @@ public class MUCLightRoomConfiguration { private final String roomName; private final String subject; - private final HashMap customConfigs; + private final Map customConfigs; /** * MUC Light room configuration model constructor. @@ -37,7 +37,7 @@ public class MUCLightRoomConfiguration { * @param subject TODO javadoc me please * @param customConfigs TODO javadoc me please */ - public MUCLightRoomConfiguration(String roomName, String subject, HashMap customConfigs) { + public MUCLightRoomConfiguration(String roomName, String subject, Map customConfigs) { this.roomName = roomName; this.subject = subject; this.customConfigs = customConfigs; @@ -66,7 +66,7 @@ public class MUCLightRoomConfiguration { * * @return the custom configurations of the room. */ - public HashMap getCustomConfigs() { + public Map getCustomConfigs() { return customConfigs; } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MUCLightRoomInfo.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MUCLightRoomInfo.java index b41066d54..532f64bf4 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MUCLightRoomInfo.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MUCLightRoomInfo.java @@ -16,7 +16,7 @@ */ package org.jivesoftware.smackx.muclight; -import java.util.HashMap; +import java.util.Map; import org.jxmpp.jid.Jid; @@ -30,7 +30,7 @@ public class MUCLightRoomInfo { private final String version; private final Jid room; private final MUCLightRoomConfiguration configuration; - private final HashMap occupants; + private final Map occupants; /** * MUC Light room info model constructor. @@ -41,7 +41,7 @@ public class MUCLightRoomInfo { * @param occupants TODO javadoc me please */ public MUCLightRoomInfo(String version, Jid roomJid, MUCLightRoomConfiguration configuration, - HashMap occupants) { + Map occupants) { this.version = version; this.room = roomJid; this.configuration = configuration; @@ -80,7 +80,7 @@ public class MUCLightRoomInfo { * * @return the occupants of the room. */ - public HashMap getOccupants() { + public Map getOccupants() { return occupants; } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MultiUserChatLight.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MultiUserChatLight.java index 77262c226..58e5b367d 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MultiUserChatLight.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MultiUserChatLight.java @@ -18,6 +18,7 @@ package org.jivesoftware.smackx.muclight; import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; @@ -279,7 +280,7 @@ public class MultiUserChatLight { * @param occupants TODO javadoc me please * @throws Exception TODO javadoc me please */ - public void create(String roomName, String subject, HashMap customConfigs, List occupants) + public void create(String roomName, String subject, Map customConfigs, List occupants) throws Exception { MUCLightCreateIQ createMUCLightIQ = new MUCLightCreateIQ(room, roomName, occupants); @@ -313,7 +314,7 @@ public class MultiUserChatLight { * @throws XMPPErrorException if there was an XMPP error returned. */ public void leave() throws NotConnectedException, InterruptedException, NoResponseException, XMPPErrorException { - HashMap affiliations = new HashMap<>(); + Map affiliations = new HashMap<>(); affiliations.put(connection.getUser(), MUCLightAffiliation.none); MUCLightChangeAffiliationsIQ changeAffiliationsIQ = new MUCLightChangeAffiliationsIQ(room, affiliations); @@ -402,7 +403,7 @@ public class MultiUserChatLight { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - public HashMap getAffiliations(String version) + public Map getAffiliations(String version) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { MUCLightGetAffiliationsIQ mucLightGetAffiliationsIQ = new MUCLightGetAffiliationsIQ(room, version); @@ -421,7 +422,7 @@ public class MultiUserChatLight { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - public HashMap getAffiliations() + public Map getAffiliations() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { return getAffiliations(null); } @@ -435,7 +436,7 @@ public class MultiUserChatLight { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - public void changeAffiliations(HashMap affiliations) + public void changeAffiliations(Map affiliations) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { MUCLightChangeAffiliationsIQ changeAffiliationsIQ = new MUCLightChangeAffiliationsIQ(room, affiliations); connection.sendIqRequestAndWaitForResponse(changeAffiliationsIQ); @@ -498,7 +499,7 @@ public class MultiUserChatLight { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - public void setRoomConfigs(HashMap customConfigs) + public void setRoomConfigs(Map customConfigs) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { setRoomConfigs(null, customConfigs); } @@ -513,7 +514,7 @@ public class MultiUserChatLight { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - public void setRoomConfigs(String roomName, HashMap customConfigs) + public void setRoomConfigs(String roomName, Map customConfigs) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { MUCLightSetConfigsIQ mucLightSetConfigIQ = new MUCLightSetConfigsIQ(room, roomName, customConfigs); connection.sendIqRequestAndWaitForResponse(mucLightSetConfigIQ); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MultiUserChatLightManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MultiUserChatLightManager.java index d153d499d..58f030499 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MultiUserChatLightManager.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MultiUserChatLightManager.java @@ -274,7 +274,7 @@ public final class MultiUserChatLightManager extends Manager { sendBlockRooms(mucLightService, rooms); } - private void sendBlockRooms(DomainBareJid mucLightService, HashMap rooms) + private void sendBlockRooms(DomainBareJid mucLightService, Map rooms) throws NoResponseException, XMPPErrorException, InterruptedException, NotConnectedException { MUCLightBlockingIQ mucLightBlockingIQ = new MUCLightBlockingIQ(rooms, null); mucLightBlockingIQ.setType(IQ.Type.set); @@ -318,7 +318,7 @@ public final class MultiUserChatLightManager extends Manager { sendBlockUsers(mucLightService, users); } - private void sendBlockUsers(DomainBareJid mucLightService, HashMap users) + private void sendBlockUsers(DomainBareJid mucLightService, Map users) throws NoResponseException, XMPPErrorException, InterruptedException, NotConnectedException { MUCLightBlockingIQ mucLightBlockingIQ = new MUCLightBlockingIQ(null, users); mucLightBlockingIQ.setType(IQ.Type.set); @@ -362,7 +362,7 @@ public final class MultiUserChatLightManager extends Manager { sendUnblockRooms(mucLightService, rooms); } - private void sendUnblockRooms(DomainBareJid mucLightService, HashMap rooms) + private void sendUnblockRooms(DomainBareJid mucLightService, Map rooms) throws NoResponseException, XMPPErrorException, InterruptedException, NotConnectedException { MUCLightBlockingIQ mucLightBlockingIQ = new MUCLightBlockingIQ(rooms, null); mucLightBlockingIQ.setType(IQ.Type.set); @@ -406,7 +406,7 @@ public final class MultiUserChatLightManager extends Manager { sendUnblockUsers(mucLightService, users); } - private void sendUnblockUsers(DomainBareJid mucLightService, HashMap users) + private void sendUnblockUsers(DomainBareJid mucLightService, Map users) throws NoResponseException, XMPPErrorException, InterruptedException, NotConnectedException { MUCLightBlockingIQ mucLightBlockingIQ = new MUCLightBlockingIQ(null, users); mucLightBlockingIQ.setType(IQ.Type.set); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightAffiliationsIQ.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightAffiliationsIQ.java index e1e8fcdf4..047c7af50 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightAffiliationsIQ.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightAffiliationsIQ.java @@ -16,7 +16,6 @@ */ package org.jivesoftware.smackx.muclight.element; -import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -40,7 +39,7 @@ public class MUCLightAffiliationsIQ extends IQ { public static final String NAMESPACE = MultiUserChatLight.NAMESPACE + MultiUserChatLight.AFFILIATIONS; private final String version; - private HashMap affiliations; + private Map affiliations; /** * MUC Light affiliations response IQ constructor. @@ -49,7 +48,7 @@ public class MUCLightAffiliationsIQ extends IQ { * @param affiliations TODO javadoc me please */ @SuppressWarnings("this-escape") - public MUCLightAffiliationsIQ(String version, HashMap affiliations) { + public MUCLightAffiliationsIQ(String version, Map affiliations) { super(ELEMENT, NAMESPACE); this.version = version; this.affiliations = affiliations; @@ -83,7 +82,7 @@ public class MUCLightAffiliationsIQ extends IQ { * * @return the affiliations of the room */ - public HashMap getAffiliations() { + public Map getAffiliations() { return affiliations; } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightBlockingIQ.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightBlockingIQ.java index f3334b651..fa6264ff0 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightBlockingIQ.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightBlockingIQ.java @@ -16,7 +16,6 @@ */ package org.jivesoftware.smackx.muclight.element; -import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -38,8 +37,8 @@ public class MUCLightBlockingIQ extends IQ { public static final String ELEMENT = QUERY_ELEMENT; public static final String NAMESPACE = MultiUserChatLight.NAMESPACE + MultiUserChatLight.BLOCKING; - private final HashMap rooms; - private final HashMap users; + private final Map rooms; + private final Map users; /** * MUC Light blocking IQ constructor. @@ -47,7 +46,7 @@ public class MUCLightBlockingIQ extends IQ { * @param rooms TODO javadoc me please * @param users TODO javadoc me please */ - public MUCLightBlockingIQ(HashMap rooms, HashMap users) { + public MUCLightBlockingIQ(Map rooms, Map users) { super(ELEMENT, NAMESPACE); this.rooms = rooms; this.users = users; @@ -58,7 +57,7 @@ public class MUCLightBlockingIQ extends IQ { * * @return the rooms JIDs with booleans (true if allow, false if deny) */ - public HashMap getRooms() { + public Map getRooms() { return rooms; } @@ -67,7 +66,7 @@ public class MUCLightBlockingIQ extends IQ { * * @return the users JIDs with booleans (true if allow, false if deny) */ - public HashMap getUsers() { + public Map getUsers() { return users; } @@ -86,7 +85,7 @@ public class MUCLightBlockingIQ extends IQ { return xml; } - private static void parseBlocking(IQChildElementXmlStringBuilder xml, HashMap map, boolean isRoom) { + private static void parseBlocking(IQChildElementXmlStringBuilder xml, Map map, boolean isRoom) { Iterator> it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry pair = it.next(); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightChangeAffiliationsIQ.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightChangeAffiliationsIQ.java index 2898ea8b6..e472c84e1 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightChangeAffiliationsIQ.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightChangeAffiliationsIQ.java @@ -16,7 +16,6 @@ */ package org.jivesoftware.smackx.muclight.element; -import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -39,7 +38,7 @@ public class MUCLightChangeAffiliationsIQ extends IQ { public static final String ELEMENT = QUERY_ELEMENT; public static final String NAMESPACE = MultiUserChatLight.NAMESPACE + MultiUserChatLight.AFFILIATIONS; - private HashMap affiliations; + private Map affiliations; /** * MUCLight change affiliations IQ constructor. @@ -48,7 +47,7 @@ public class MUCLightChangeAffiliationsIQ extends IQ { * @param affiliations TODO javadoc me please */ @SuppressWarnings("this-escape") - public MUCLightChangeAffiliationsIQ(Jid room, HashMap affiliations) { + public MUCLightChangeAffiliationsIQ(Jid room, Map affiliations) { super(ELEMENT, NAMESPACE); this.setType(Type.set); this.setTo(room); @@ -60,7 +59,7 @@ public class MUCLightChangeAffiliationsIQ extends IQ { * * @return the affiliations */ - public HashMap getAffiliations() { + public Map getAffiliations() { return affiliations; } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightCreateIQ.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightCreateIQ.java index afd8efd90..ea0db3b21 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightCreateIQ.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightCreateIQ.java @@ -18,6 +18,7 @@ package org.jivesoftware.smackx.muclight.element; import java.util.HashMap; import java.util.List; +import java.util.Map; import org.jivesoftware.smack.packet.IQ; @@ -42,7 +43,7 @@ public class MUCLightCreateIQ extends IQ { public static final String NAMESPACE = MultiUserChatLight.NAMESPACE + MultiUserChatLight.CREATE; private MUCLightRoomConfiguration configuration; - private final HashMap occupants; + private final Map occupants; /** * MUCLight create IQ constructor. @@ -54,7 +55,7 @@ public class MUCLightCreateIQ extends IQ { * @param occupants TODO javadoc me please */ @SuppressWarnings("this-escape") - public MUCLightCreateIQ(EntityJid room, String roomName, String subject, HashMap customConfigs, + public MUCLightCreateIQ(EntityJid room, String roomName, String subject, Map customConfigs, List occupants) { super(ELEMENT, NAMESPACE); this.configuration = new MUCLightRoomConfiguration(roomName, subject, customConfigs); @@ -93,7 +94,7 @@ public class MUCLightCreateIQ extends IQ { * * @return the room occupants */ - public HashMap getOccupants() { + public Map getOccupants() { return occupants; } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightElements.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightElements.java index 33861b29e..27dcbd2e7 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightElements.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightElements.java @@ -16,7 +16,6 @@ */ package org.jivesoftware.smackx.muclight.element; -import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -48,11 +47,11 @@ public abstract class MUCLightElements { public static final String NAMESPACE = MultiUserChatLight.NAMESPACE + MultiUserChatLight.AFFILIATIONS; public static final QName QNAME = new QName(NAMESPACE, ELEMENT); - private final HashMap affiliations; + private final Map affiliations; private final String prevVersion; private final String version; - public AffiliationsChangeExtension(HashMap affiliations, String prevVersion, + public AffiliationsChangeExtension(Map affiliations, String prevVersion, String version) { this.affiliations = affiliations; this.prevVersion = prevVersion; @@ -74,7 +73,7 @@ public abstract class MUCLightElements { * * @return the affiliations */ - public HashMap getAffiliations() { + public Map getAffiliations() { return affiliations; } @@ -135,7 +134,7 @@ public abstract class MUCLightElements { private final String version; private final String roomName; private final String subject; - private final HashMap customConfigs; + private final Map customConfigs; /** * Configurations change extension constructor. @@ -147,7 +146,7 @@ public abstract class MUCLightElements { * @param customConfigs TODO javadoc me please */ public ConfigurationsChangeExtension(String prevVersion, String version, String roomName, String subject, - HashMap customConfigs) { + Map customConfigs) { this.prevVersion = prevVersion; this.version = version; this.roomName = roomName; @@ -206,7 +205,7 @@ public abstract class MUCLightElements { * * @return the room custom configurations */ - public HashMap getCustomConfigs() { + public Map getCustomConfigs() { return customConfigs; } @@ -287,14 +286,14 @@ public abstract class MUCLightElements { */ public static class OccupantsElement implements Element { - private HashMap occupants; + private Map occupants; /** * Occupants element constructor. * * @param occupants TODO javadoc me please */ - public OccupantsElement(HashMap occupants) { + public OccupantsElement(Map occupants) { this.occupants = occupants; } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightInfoIQ.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightInfoIQ.java index 42a2b9308..ef33d4b77 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightInfoIQ.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightInfoIQ.java @@ -16,7 +16,7 @@ */ package org.jivesoftware.smackx.muclight.element; -import java.util.HashMap; +import java.util.Map; import org.jivesoftware.smack.packet.IQ; @@ -41,7 +41,7 @@ public class MUCLightInfoIQ extends IQ { private final String version; private final MUCLightRoomConfiguration configuration; - private final HashMap occupants; + private final Map occupants; /** * MUCLight info response IQ constructor. @@ -51,7 +51,7 @@ public class MUCLightInfoIQ extends IQ { * @param occupants TODO javadoc me please */ public MUCLightInfoIQ(String version, MUCLightRoomConfiguration configuration, - HashMap occupants) { + Map occupants) { super(ELEMENT, NAMESPACE); this.version = version; this.configuration = configuration; @@ -90,7 +90,7 @@ public class MUCLightInfoIQ extends IQ { * * @return the occupants of the room */ - public HashMap getOccupants() { + public Map getOccupants() { return occupants; } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightSetConfigsIQ.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightSetConfigsIQ.java index 6ab25a9ed..3e332194a 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightSetConfigsIQ.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/element/MUCLightSetConfigsIQ.java @@ -16,7 +16,6 @@ */ package org.jivesoftware.smackx.muclight.element; -import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -39,7 +38,7 @@ public class MUCLightSetConfigsIQ extends IQ { private String roomName; private String subject; - private HashMap customConfigs; + private Map customConfigs; /** * MUC Light set configuration IQ constructor. @@ -50,7 +49,7 @@ public class MUCLightSetConfigsIQ extends IQ { * @param customConfigs TODO javadoc me please */ @SuppressWarnings("this-escape") - public MUCLightSetConfigsIQ(Jid roomJid, String roomName, String subject, HashMap customConfigs) { + public MUCLightSetConfigsIQ(Jid roomJid, String roomName, String subject, Map customConfigs) { super(ELEMENT, NAMESPACE); this.roomName = roomName; this.subject = subject; @@ -66,7 +65,7 @@ public class MUCLightSetConfigsIQ extends IQ { * @param roomName TODO javadoc me please * @param customConfigs TODO javadoc me please */ - public MUCLightSetConfigsIQ(Jid roomJid, String roomName, HashMap customConfigs) { + public MUCLightSetConfigsIQ(Jid roomJid, String roomName, Map customConfigs) { this(roomJid, roomName, null, customConfigs); } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/provider/MUCLightBlockingIQProvider.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/provider/MUCLightBlockingIQProvider.java index b89dba5c8..1412b2900 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/provider/MUCLightBlockingIQProvider.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/provider/MUCLightBlockingIQProvider.java @@ -18,6 +18,7 @@ package org.jivesoftware.smackx.muclight.provider; import java.io.IOException; import java.util.HashMap; +import java.util.Map; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IqData; @@ -42,8 +43,8 @@ public class MUCLightBlockingIQProvider extends IqProvider { @Override public MUCLightBlockingIQ parse(XmlPullParser parser, int initialDepth, IqData iqData, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException { - HashMap rooms = null; - HashMap users = null; + Map rooms = null; + Map users = null; outerloop: while (true) { XmlPullParser.Event eventType = parser.next(); @@ -70,7 +71,7 @@ public class MUCLightBlockingIQProvider extends IqProvider { return mucLightBlockingIQ; } - private static HashMap parseBlocking(XmlPullParser parser, HashMap map) + private static Map parseBlocking(XmlPullParser parser, Map map) throws XmppStringprepException, XmlPullParserException, IOException { if (map == null) { map = new HashMap<>(); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/provider/MUCLightInfoIQProvider.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/provider/MUCLightInfoIQProvider.java index 54d0a4218..50d30bca4 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/provider/MUCLightInfoIQProvider.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/provider/MUCLightInfoIQProvider.java @@ -18,6 +18,7 @@ package org.jivesoftware.smackx.muclight.provider; import java.io.IOException; import java.util.HashMap; +import java.util.Map; import org.jivesoftware.smack.packet.IqData; import org.jivesoftware.smack.packet.XmlEnvironment; @@ -45,8 +46,8 @@ public class MUCLightInfoIQProvider extends IqProvider { String version = null; String roomName = null; String subject = null; - HashMap customConfigs = null; - HashMap occupants = new HashMap<>(); + Map customConfigs = null; + Map occupants = new HashMap<>(); outerloop: while (true) { XmlPullParser.Event eventType = parser.next(); @@ -97,8 +98,8 @@ public class MUCLightInfoIQProvider extends IqProvider { return new MUCLightInfoIQ(version, new MUCLightRoomConfiguration(roomName, subject, customConfigs), occupants); } - private static HashMap iterateOccupants(XmlPullParser parser) throws XmlPullParserException, IOException { - HashMap occupants = new HashMap<>(); + private static Map iterateOccupants(XmlPullParser parser) throws XmlPullParserException, IOException { + Map occupants = new HashMap<>(); int depth = parser.getDepth(); outerloop: while (true) { diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/push_notifications/PushNotificationsManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/push_notifications/PushNotificationsManager.java index ff62d96eb..8615b4759 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/push_notifications/PushNotificationsManager.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/push_notifications/PushNotificationsManager.java @@ -16,7 +16,6 @@ */ package org.jivesoftware.smackx.push_notifications; -import java.util.HashMap; import java.util.Map; import java.util.WeakHashMap; @@ -122,7 +121,7 @@ public final class PushNotificationsManager extends Manager { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - public boolean enable(Jid pushJid, String node, HashMap publishOptions) + public boolean enable(Jid pushJid, String node, Map publishOptions) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { EnablePushNotificationsIQ enablePushNotificationsIQ = new EnablePushNotificationsIQ(pushJid, node, publishOptions); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/push_notifications/element/EnablePushNotificationsIQ.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/push_notifications/element/EnablePushNotificationsIQ.java index 643de425a..c6f8199b4 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/push_notifications/element/EnablePushNotificationsIQ.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/push_notifications/element/EnablePushNotificationsIQ.java @@ -16,7 +16,6 @@ */ package org.jivesoftware.smackx.push_notifications.element; -import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -51,10 +50,10 @@ public class EnablePushNotificationsIQ extends IQ { private final Jid jid; private final String node; - private final HashMap publishOptions; + private final Map publishOptions; @SuppressWarnings("this-escape") - public EnablePushNotificationsIQ(Jid jid, String node, HashMap publishOptions) { + public EnablePushNotificationsIQ(Jid jid, String node, Map publishOptions) { super(ELEMENT, NAMESPACE); this.jid = jid; this.node = node; @@ -89,7 +88,7 @@ public class EnablePushNotificationsIQ extends IQ { * * @return the publish options */ - public HashMap getPublishOptions() { + public Map getPublishOptions() { return publishOptions; } diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/muclight/MUCLightAffiliationsChangeExtensionTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/muclight/MUCLightAffiliationsChangeExtensionTest.java index a07577748..ab9e53750 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/muclight/MUCLightAffiliationsChangeExtensionTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/muclight/MUCLightAffiliationsChangeExtensionTest.java @@ -18,7 +18,7 @@ package org.jivesoftware.smackx.muclight; import static org.junit.jupiter.api.Assertions.assertEquals; -import java.util.HashMap; +import java.util.Map; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.util.PacketParserUtils; @@ -55,7 +55,7 @@ public class MUCLightAffiliationsChangeExtensionTest { AffiliationsChangeExtension affiliationsChangeExtension = AffiliationsChangeExtension .from(changeAffiliationsMessage); - HashMap affiliations = affiliationsChangeExtension.getAffiliations(); + Map affiliations = affiliationsChangeExtension.getAffiliations(); assertEquals(affiliations.size(), 3); assertEquals(affiliations.get(JidCreate.from("sarasa2@shakespeare.lit")), MUCLightAffiliation.owner); assertEquals(affiliations.get(JidCreate.from("sarasa1@shakespeare.lit")), MUCLightAffiliation.member); @@ -68,7 +68,7 @@ public class MUCLightAffiliationsChangeExtensionTest { AffiliationsChangeExtension affiliationsChangeExtension = AffiliationsChangeExtension .from(changeAffiliationsMessage); - HashMap affiliations = affiliationsChangeExtension.getAffiliations(); + Map affiliations = affiliationsChangeExtension.getAffiliations(); assertEquals(affiliations.size(), 2); assertEquals(affiliations.get(JidCreate.from("sarasa1@shakespeare.lit")), MUCLightAffiliation.member); assertEquals(affiliations.get(JidCreate.from("sarasa3@shakespeare.lit")), MUCLightAffiliation.none); @@ -83,7 +83,7 @@ public class MUCLightAffiliationsChangeExtensionTest { AffiliationsChangeExtension affiliationsChangeExtension = AffiliationsChangeExtension .from(changeAffiliationsMessage); - HashMap affiliations = affiliationsChangeExtension.getAffiliations(); + Map affiliations = affiliationsChangeExtension.getAffiliations(); assertEquals(affiliations.size(), 2); assertEquals(affiliations.get(JidCreate.from("sarasa2@shakespeare.lit")), MUCLightAffiliation.owner); assertEquals(affiliations.get(JidCreate.from("sarasa1@shakespeare.lit")), MUCLightAffiliation.member); diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/muclight/MUCLightChangeAffiliationsIQTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/muclight/MUCLightChangeAffiliationsIQTest.java index efbb22da7..ca0e1e4cb 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/muclight/MUCLightChangeAffiliationsIQTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/muclight/MUCLightChangeAffiliationsIQTest.java @@ -19,6 +19,7 @@ package org.jivesoftware.smackx.muclight; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.HashMap; +import java.util.Map; import org.jivesoftware.smack.packet.IQ; @@ -32,7 +33,7 @@ public class MUCLightChangeAffiliationsIQTest { @Test public void checkChangeAffiliationsMUCLightStanza() throws Exception { - HashMap affiliations = new HashMap<>(); + Map affiliations = new HashMap<>(); affiliations.put(JidCreate.from("sarasa2@shakespeare.lit"), MUCLightAffiliation.owner); affiliations.put(JidCreate.from("sarasa1@shakespeare.lit"), MUCLightAffiliation.member); affiliations.put(JidCreate.from("sarasa3@shakespeare.lit"), MUCLightAffiliation.none); @@ -44,7 +45,7 @@ public class MUCLightChangeAffiliationsIQTest { assertEquals(mucLightChangeAffiliationsIQ.getTo(), "coven@muclight.shakespeare.lit"); assertEquals(mucLightChangeAffiliationsIQ.getType(), IQ.Type.set); - HashMap iqAffiliations = mucLightChangeAffiliationsIQ.getAffiliations(); + Map iqAffiliations = mucLightChangeAffiliationsIQ.getAffiliations(); assertEquals(iqAffiliations.get(JidCreate.from("sarasa1@shakespeare.lit")), MUCLightAffiliation.member); assertEquals(iqAffiliations.get(JidCreate.from("sarasa2@shakespeare.lit")), MUCLightAffiliation.owner); assertEquals(iqAffiliations.get(JidCreate.from("sarasa3@shakespeare.lit")), MUCLightAffiliation.none); diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/muclight/MUCLightCreateIQTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/muclight/MUCLightCreateIQTest.java index 216a2a494..4a92da24e 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/muclight/MUCLightCreateIQTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/muclight/MUCLightCreateIQTest.java @@ -19,8 +19,8 @@ package org.jivesoftware.smackx.muclight; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; +import java.util.Map; import org.jivesoftware.smackx.muclight.element.MUCLightCreateIQ; @@ -43,7 +43,7 @@ public class MUCLightCreateIQTest { assertEquals(mucLightCreateIQ.getConfiguration().getRoomName(), "test"); - HashMap iqOccupants = mucLightCreateIQ.getOccupants(); + Map iqOccupants = mucLightCreateIQ.getOccupants(); assertEquals(iqOccupants.get(JidCreate.from("charlie@test.com")), MUCLightAffiliation.member); assertEquals(iqOccupants.get(JidCreate.from("pep@test.com")), MUCLightAffiliation.member); } diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/muclight/MUCLightGetAffiliationsTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/muclight/MUCLightGetAffiliationsTest.java index 782171ae1..5504468ef 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/muclight/MUCLightGetAffiliationsTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/muclight/MUCLightGetAffiliationsTest.java @@ -18,7 +18,7 @@ package org.jivesoftware.smackx.muclight; import static org.junit.jupiter.api.Assertions.assertEquals; -import java.util.HashMap; +import java.util.Map; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.StreamOpen; @@ -57,7 +57,7 @@ public class MUCLightGetAffiliationsTest { assertEquals("123456", mucLightAffiliationsIQ.getVersion()); - HashMap affiliations = mucLightAffiliationsIQ.getAffiliations(); + Map affiliations = mucLightAffiliationsIQ.getAffiliations(); assertEquals(3, affiliations.size()); assertEquals(MUCLightAffiliation.owner, affiliations.get(JidCreate.from("user1@shakespeare.lit"))); assertEquals(MUCLightAffiliation.member, affiliations.get(JidCreate.from("user2@shakespeare.lit"))); diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/muclight/MUCLightGetConfigsTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/muclight/MUCLightGetConfigsTest.java index 8c295ab0e..02826d8d1 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/muclight/MUCLightGetConfigsTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/muclight/MUCLightGetConfigsTest.java @@ -19,7 +19,7 @@ package org.jivesoftware.smackx.muclight; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -import java.util.HashMap; +import java.util.Map; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.StreamOpen; @@ -74,7 +74,7 @@ public class MUCLightGetConfigsTest { assertEquals("A Dark Cave", mucLightConfigurationIQ.getConfiguration().getRoomName()); assertNull(mucLightConfigurationIQ.getConfiguration().getSubject()); - HashMap customConfigs = mucLightConfigurationIQ.getConfiguration().getCustomConfigs(); + Map customConfigs = mucLightConfigurationIQ.getConfiguration().getCustomConfigs(); assertEquals("blue", customConfigs.get("color")); assertEquals("20", customConfigs.get("size")); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandManager.java index 4f4b0652b..568b98a14 100755 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandManager.java @@ -85,7 +85,7 @@ public final class AdHocCommandManager extends Manager { */ private static final Map instances = new WeakHashMap<>(); - /** + /* * Register the listener for all the connection creations. When a new * connection is created a new AdHocCommandManager is also created and * related to that connection. @@ -463,7 +463,7 @@ public final class AdHocCommandManager extends Manager { private AdHocCommandData processAdHocCommandOfExistingSession(AdHocCommandData request, AdHocCommandHandler command, AdHocCommandDataBuilder responseBuilder) { // Check if the Session data has expired (default is 10 minutes) long creationStamp = command.getCreationDate(); - if (System.currentTimeMillis() - creationStamp > sessionTimeoutSecs * 1000) { + if (System.currentTimeMillis() - creationStamp > sessionTimeoutSecs * 1000L) { // Remove the expired session executingCommands.remove(command.getSessionId()); @@ -553,7 +553,7 @@ public final class AdHocCommandManager extends Manager { // after the time out, then once the user requests to // continue the execution he will received an // invalid session error and not a time out error. - if (currentTime - creationStamp > getSessionRemovalTimeoutSecs() * 1000) { + if (currentTime - creationStamp > getSessionRemovalTimeoutSecs() * 1000L) { // Remove the expired session it.remove(); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/provider/JivePropertiesExtensionProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/provider/JivePropertiesExtensionProvider.java index 6d99c1637..8326e93e5 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/provider/JivePropertiesExtensionProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/provider/JivePropertiesExtensionProvider.java @@ -46,7 +46,7 @@ public class JivePropertiesExtensionProvider extends ExtensionElementProvider - * Note that you have to explicitly enabled Java object deserialization with @{link + * Note that you have to explicitly enabled Java object deserialization with * {@link JivePropertiesManager#setJavaObjectEnabled(boolean)} * * @param parser the XML parser, positioned at the start of a properties sub-packet. 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 847651f21..fa87fdd37 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 @@ -143,7 +143,6 @@ public final class PrivacyListManager extends Manager { else { cachedActiveListName = activeListName; } - return; } }, iqResultReplyFilter); } @@ -165,7 +164,6 @@ public final class PrivacyListManager extends Manager { else { cachedDefaultListName = defaultListName; } - return; } }, iqResultReplyFilter); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/FormField.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/FormField.java index 7465f6d2d..bd172be54 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/FormField.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/FormField.java @@ -386,7 +386,7 @@ public abstract class FormField implements XmlElement { protected transient List extraXmlChildElements; /** - * Populate @{link {@link #extraXmlChildElements}}. Note that this method may be overridden by subclasses. + * Populate {@link #extraXmlChildElements}. Note that this method may be overridden by subclasses. */ protected void populateExtraXmlChildElements() { List values = getRawValues(); diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java index 00e721e5b..0c59cf73c 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java @@ -179,7 +179,7 @@ public class Socks5ByteStreamManagerTest { Socks5BytestreamManager byteStreamManager = Socks5BytestreamManager.getBytestreamManager(connection); byteStreamManager.setAnnounceLocalStreamHost(false); - /** + /* * create responses in the order they should be queried specified by the XEP-0065 * specification */ @@ -231,7 +231,7 @@ public class Socks5ByteStreamManagerTest { Socks5BytestreamManager byteStreamManager = Socks5BytestreamManager.getBytestreamManager(connection); byteStreamManager.setAnnounceLocalStreamHost(false); - /** + /* * create responses in the order they should be queried specified by the XEP-0065 * specification */ @@ -292,7 +292,7 @@ public class Socks5ByteStreamManagerTest { Socks5BytestreamManager byteStreamManager = Socks5BytestreamManager.getBytestreamManager(connection); byteStreamManager.setAnnounceLocalStreamHost(false); - /** + /* * create responses in the order they should be queried specified by the XEP-0065 * specification */ @@ -375,7 +375,7 @@ public class Socks5ByteStreamManagerTest { Socks5BytestreamManager byteStreamManager = Socks5BytestreamManager.getBytestreamManager(connection); byteStreamManager.setAnnounceLocalStreamHost(false); - /** + /* * create responses in the order they should be queried specified by the XEP-0065 * specification */ @@ -454,7 +454,7 @@ public class Socks5ByteStreamManagerTest { // TODO: It appears that it is not required to disable the local stream host for this unit test. byteStreamManager.setAnnounceLocalStreamHost(false); - /** + /* * create responses in the order they should be queried specified by the XEP-0065 * specification */ @@ -541,7 +541,7 @@ public class Socks5ByteStreamManagerTest { byteStreamManager.setAnnounceLocalStreamHost(false); byteStreamManager.setProxyConnectionTimeout(3000); - /** + /* * create responses in the order they should be queried specified by the XEP-0065 * specification */ @@ -634,7 +634,7 @@ public class Socks5ByteStreamManagerTest { Socks5BytestreamManager byteStreamManager = Socks5BytestreamManager.getBytestreamManager(connection); byteStreamManager.setAnnounceLocalStreamHost(false); - /** + /* * create responses in the order they should be queried specified by the XEP-0065 * specification */ @@ -760,7 +760,7 @@ public class Socks5ByteStreamManagerTest { // get Socks5ByteStreamManager for connection Socks5BytestreamManager byteStreamManager = Socks5BytestreamManager.getBytestreamManager(connection); - /** + /* * create responses in the order they should be queried specified by the XEP-0065 * specification */ diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java index 889f9bb9c..fab1e00c9 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java @@ -28,6 +28,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.Set; @@ -787,6 +788,6 @@ public final class Configuration { if (specification == null || specification.isBlank()) { return null; } - return specification.replaceAll("[\\s-]", "").toUpperCase(); + return specification.replaceAll("[\\s-]", "").toUpperCase(Locale.ROOT); } } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/httpfileupload/HttpFileUploadIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/httpfileupload/HttpFileUploadIntegrationTest.java index f68ab7b61..862a06af2 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/httpfileupload/HttpFileUploadIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/httpfileupload/HttpFileUploadIntegrationTest.java @@ -82,7 +82,7 @@ public class HttpFileUploadIntegrationTest extends AbstractSmackIntegrationTest URL getUrl = hfumOne.uploadFile(file, new UploadProgressListener() { @Override public void onUploadProgress(long uploadedBytes, long totalBytes) { - double progress = uploadedBytes / totalBytes; + double progress = uploadedBytes / ((double) totalBytes); LOGGER.fine("HTTP File Upload progress " + progress + "% (" + uploadedBytes + '/' + totalBytes + ')'); } }); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoManagerSetupHelper.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoManagerSetupHelper.java index 1a8093d63..7fdf53165 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoManagerSetupHelper.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoManagerSetupHelper.java @@ -21,8 +21,8 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.IOException; -import java.util.HashMap; import java.util.List; +import java.util.Map; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.SmackException.NotConnectedException; @@ -54,7 +54,7 @@ public class OmemoManagerSetupHelper { } alice.requestDeviceListUpdateFor(bob.getOwnJid()); - HashMap fingerprints = alice.getActiveFingerprints(bob.getOwnJid()); + Map fingerprints = alice.getActiveFingerprints(bob.getOwnJid()); for (OmemoDevice device : fingerprints.keySet()) { OmemoFingerprint fingerprint = fingerprints.get(device); @@ -67,7 +67,7 @@ public class OmemoManagerSetupHelper { SmackException.NoResponseException, CannotEstablishOmemoSessionException, CorruptedOmemoKeyException, XMPPException.XMPPErrorException, PubSubException.NotALeafNodeException, IOException { alice.requestDeviceListUpdateFor(bob.getOwnJid()); - HashMap fps1 = alice.getActiveFingerprints(bob.getOwnJid()); + Map fps1 = alice.getActiveFingerprints(bob.getOwnJid()); assertFalse(fps1.isEmpty()); assertAllDevicesAreUndecided(alice, fps1); @@ -75,7 +75,7 @@ public class OmemoManagerSetupHelper { trustAllIdentities(alice, bob); - HashMap fps2 = alice.getActiveFingerprints(bob.getOwnJid()); + Map fps2 = alice.getActiveFingerprints(bob.getOwnJid()); assertEquals(fps1.size(), fps2.size()); assertTrue(Maps.difference(fps1, fps2).areEqual()); @@ -95,28 +95,28 @@ public class OmemoManagerSetupHelper { return manager; } - public static void assertAllDevicesAreUndecided(OmemoManager manager, HashMap devices) { + public static void assertAllDevicesAreUndecided(OmemoManager manager, Map devices) { for (OmemoDevice device : devices.keySet()) { // All fingerprints MUST be neither decided, nor trusted. assertFalse(manager.isDecidedOmemoIdentity(device, devices.get(device))); } } - public static void assertAllDevicesAreUntrusted(OmemoManager manager, HashMap devices) { + public static void assertAllDevicesAreUntrusted(OmemoManager manager, Map devices) { for (OmemoDevice device : devices.keySet()) { // All fingerprints MUST be neither decided, nor trusted. assertFalse(manager.isTrustedOmemoIdentity(device, devices.get(device))); } } - public static void assertAllDevicesAreDecided(OmemoManager manager, HashMap devices) { + public static void assertAllDevicesAreDecided(OmemoManager manager, Map devices) { for (OmemoDevice device : devices.keySet()) { // All fingerprints MUST be neither decided, nor trusted. assertTrue(manager.isDecidedOmemoIdentity(device, devices.get(device))); } } - public static void assertAllDevicesAreTrusted(OmemoManager manager, HashMap devices) { + public static void assertAllDevicesAreTrusted(OmemoManager manager, Map devices) { for (OmemoDevice device : devices.keySet()) { // All fingerprints MUST be neither decided, nor trusted. assertTrue(manager.isTrustedOmemoIdentity(device, devices.get(device))); diff --git a/smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFrameWorkTest.java b/smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFrameWorkTest.java index 48b827770..fbdfa8cef 100644 --- a/smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFrameWorkTest.java +++ b/smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFrameWorkTest.java @@ -31,26 +31,26 @@ import org.junit.jupiter.api.Test; public class SmackIntegrationTestFrameWorkTest { private static class ValidLowLevelList { - @SuppressWarnings("unused") + @SuppressWarnings({"unused", "MethodCanBeStatic"}) public void test(List connections) { } } private static class InvalidLowLevelList { - @SuppressWarnings("unused") + @SuppressWarnings({"unused", "MethodCanBeStatic"}) public void test(List connections, boolean invalid) { } } private static class ValidLowLevelVarargs { - @SuppressWarnings("unused") + @SuppressWarnings({"unused", "MethodCanBeStatic"}) public void test(AbstractXMPPConnection connectionOne, AbstractXMPPConnection connectionTwo, AbstractXMPPConnection connectionThree) { } } private static class InvalidLowLevelVarargs { - @SuppressWarnings("unused") + @SuppressWarnings({"unused", "MethodCanBeStatic"}) public void test(AbstractXMPPConnection connectionOne, Integer invalid, AbstractXMPPConnection connectionTwo, AbstractXMPPConnection connectionThree) { } @@ -97,7 +97,7 @@ public class SmackIntegrationTestFrameWorkTest { } private static class ValidUnconnectedConnectionSource { - @SuppressWarnings("unused") + @SuppressWarnings({"unused", "MethodCanBeStatic"}) public void test(AbstractSmackLowLevelIntegrationTest.UnconnectedConnectionSource source) { } } diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/JMFInit.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/JMFInit.java index d41cdcb5f..c86734cc2 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/JMFInit.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/JMFInit.java @@ -43,7 +43,7 @@ public class JMFInit extends Frame implements Runnable { private boolean visible = false; - @SuppressWarnings("this-escape") + @SuppressWarnings({"this-escape", "DoNotCall"}) public JMFInit(String[] args, boolean visible) { super("Initializing JMF..."); diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jspeex/AudioMediaSession.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jspeex/AudioMediaSession.java index 162483cd7..2874327ca 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jspeex/AudioMediaSession.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jspeex/AudioMediaSession.java @@ -76,12 +76,12 @@ public class AudioMediaSession extends JingleMediaSession implements MediaSessio public static MediaSession createSession(String localhost, int localPort, String remoteHost, int remotePort, MediaSessionListener eventHandler, int quality, boolean secure, boolean micOn) throws NoProcessorException, UnsupportedFormatException, IOException, GeneralSecurityException { SpeexFormat.setFramesPerPacket(1); - /** + /* * The master key. Hardcoded for now. */ byte[] masterKey = new byte[] {(byte) 0xE1, (byte) 0xF9, 0x7A, 0x0D, 0x3E, 0x01, (byte) 0x8B, (byte) 0xE0, (byte) 0xD6, 0x4F, (byte) 0xA3, 0x2C, 0x06, (byte) 0xDE, 0x41, 0x39}; - /** + /* * The master salt. Hardcoded for now. */ byte[] masterSalt = new byte[] {0x0E, (byte) 0xC6, 0x75, (byte) 0xAD, 0x49, (byte) 0x8A, (byte) 0xFE, (byte) 0xEB, (byte) 0xB6, (byte) 0x96, 0x0B, 0x3A, (byte) 0xAB, (byte) 0xE6}; diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/STUNResolver.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/STUNResolver.java index b0b010f81..7eb49df5e 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/STUNResolver.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/STUNResolver.java @@ -23,6 +23,7 @@ import java.net.SocketException; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; +import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -135,7 +136,7 @@ public class STUNResolver extends TransportResolver { * @param stunConfigStream An InputStream with the configuration file. * @return A list of loaded servers */ - public ArrayList loadSTUNServers(java.io.InputStream stunConfigStream) { + public List loadSTUNServers(java.io.InputStream stunConfigStream) { ArrayList serversList = new ArrayList<>(); String serverName; int serverPort; @@ -211,7 +212,7 @@ public class STUNResolver extends TransportResolver { * * @return a list of services */ - public ArrayList loadSTUNServers() { + public List loadSTUNServers() { ArrayList serversList = new ArrayList<>(); // Load the STUN configuration @@ -248,7 +249,7 @@ public class STUNResolver extends TransportResolver { * * @return the best STUN server that can be used. */ - private static STUNService bestSTUNServer(ArrayList listServers) { + private static STUNService bestSTUNServer(List listServers) { if (listServers.isEmpty()) { return null; } else { diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TransportCandidate.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TransportCandidate.java index 103286862..a9f3f7f8a 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TransportCandidate.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TransportCandidate.java @@ -17,13 +17,13 @@ package org.jivesoftware.smackx.jingleold.nat; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -661,21 +661,13 @@ public abstract class TransportCandidate { String local = id.substring(0, keySplitIndex) + ";" + localUser; String remote = id.substring(keySplitIndex) + ";" + remoteUser; - try { - if (session.getConnection().getUser().equals(session.getInitiator())) { - - this.send = local.getBytes("UTF-8"); - this.receive = remote.getBytes("UTF-8"); - } else { - this.receive = local.getBytes("UTF-8"); - this.send = remote.getBytes("UTF-8"); - } + if (session.getConnection().getUser().equals(session.getInitiator())) { + this.send = local.getBytes(StandardCharsets.UTF_8); + this.receive = remote.getBytes(StandardCharsets.UTF_8); + } else { + this.receive = local.getBytes(StandardCharsets.UTF_8); + this.send = remote.getBytes(StandardCharsets.UTF_8); } - catch (UnsupportedEncodingException e) { - LOGGER.log(Level.WARNING, "exception", e); - } - - } @SuppressWarnings("UnusedVariable") @@ -706,7 +698,7 @@ public abstract class TransportCandidate { long delay = 100 / replyTries; - String[] str = new String(packet.getData(), "UTF-8").split(";"); + String[] str = new String(packet.getData(), StandardCharsets.UTF_8).split(";"); String pass = str[0]; String[] address = str[1].split(":"); String ip = address[0]; @@ -714,13 +706,7 @@ public abstract class TransportCandidate { if (pass.equals(candidate.getPassword()) && !accept) { - byte[] cont = null; - try { - cont = (password + ";" + candidate.getIp() + ":" + candidate.getPort()).getBytes("UTF-8"); - } - catch (UnsupportedEncodingException e) { - LOGGER.log(Level.WARNING, "exception", e); - } + byte[] cont = (password + ";" + candidate.getIp() + ":" + candidate.getPort()).getBytes(StandardCharsets.UTF_8); packet.setData(cont); packet.setLength(cont.length); @@ -778,31 +764,24 @@ public abstract class TransportCandidate { DatagramListener listener = new DatagramListener() { @Override public boolean datagramReceived(DatagramPacket datagramPacket) { + LOGGER.fine("ECHO Received to: " + candidate.getIp() + ":" + candidate.getPort() + " data: " + new String(datagramPacket.getData(), StandardCharsets.UTF_8)); + String[] str = new String(datagramPacket.getData(), StandardCharsets.UTF_8).split(";"); + String pass = str[0]; + String[] addr = str[1].split(":"); + String ip = addr[0]; + String pt = addr[1]; - try { - LOGGER.fine("ECHO Received to: " + candidate.getIp() + ":" + candidate.getPort() + " data: " + new String(datagramPacket.getData(), "UTF-8")); - String[] str = new String(datagramPacket.getData(), "UTF-8").split(";"); - String pass = str[0]; - String[] addr = str[1].split(":"); - String ip = addr[0]; - String pt = addr[1]; - - // CHECKSTYLE:OFF - if (pass.equals(password) - && transportCandidate.getIp().indexOf(ip) != -1 - && transportCandidate.getPort() == Integer.parseInt(pt)) { - // CHECKSTYLE:ON - LOGGER.fine("ECHO OK: " + candidate.getIp() + ":" + candidate.getPort() + " <-> " + transportCandidate.getIp() + ":" + transportCandidate.getPort()); - TestResult testResult = new TestResult(); - testResult.setResult(true); - ended = true; - fireTestResult(testResult, transportCandidate); - return true; - } - - } - catch (UnsupportedEncodingException e) { - LOGGER.log(Level.WARNING, "exception", e); + // CHECKSTYLE:OFF + if (pass.equals(password) + && transportCandidate.getIp().indexOf(ip) != -1 + && transportCandidate.getPort() == Integer.parseInt(pt)) { + // CHECKSTYLE:ON + LOGGER.fine("ECHO OK: " + candidate.getIp() + ":" + candidate.getPort() + " <-> " + transportCandidate.getIp() + ":" + transportCandidate.getPort()); + TestResult testResult = new TestResult(); + testResult.setResult(true); + ended = true; + fireTestResult(testResult, transportCandidate); + return true; } LOGGER.fine("ECHO Wrong Data: " + datagramPacket.getAddress().getHostAddress() + ":" + datagramPacket.getPort()); @@ -812,13 +791,7 @@ public abstract class TransportCandidate { addListener(listener); - byte[] content = null; - try { - content = new String(password + ";" + getIp() + ":" + getPort()).getBytes("UTF-8"); - } - catch (UnsupportedEncodingException e) { - LOGGER.log(Level.WARNING, "exception", e); - } + byte[] content = new String(password + ";" + getIp() + ":" + getPort()).getBytes(StandardCharsets.UTF_8); DatagramPacket packet = new DatagramPacket(content, content.length); diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TransportNegotiator.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TransportNegotiator.java index 73bf75e9c..c61ffd46f 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TransportNegotiator.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TransportNegotiator.java @@ -311,7 +311,7 @@ public abstract class TransportNegotiator extends JingleNegotiator { // Sleep for some time, waiting for the candidates checks int totalTime = CANDIDATES_ACCEPT_PERIOD + TransportResolver.CHECK_TIMEOUT; - int tries = (int) Math.ceil(totalTime / 1000); + int tries = (int) Math.ceil(totalTime / 1000.0); for (int i = 0; i < tries - 1; i++) { try { @@ -478,7 +478,7 @@ public abstract class TransportNegotiator extends JingleNegotiator { * * @return The list of valid (ie, already checked) remote candidates. */ - final ArrayList getValidRemoteCandidatesList() { + final List getValidRemoteCandidatesList() { synchronized (validRemoteCandidates) { return new ArrayList<>(validRemoteCandidates); } @@ -872,7 +872,7 @@ public abstract class TransportNegotiator extends JingleNegotiator { @Override public TransportCandidate getBestRemoteCandidate() { // Hopefully, we only have one validRemoteCandidate - ArrayList cands = getValidRemoteCandidatesList(); + List cands = getValidRemoteCandidatesList(); if (!cands.isEmpty()) { LOGGER.fine("RAW CAND"); return cands.get(0); @@ -930,7 +930,7 @@ public abstract class TransportNegotiator extends JingleNegotiator { public TransportCandidate getBestRemoteCandidate() { ICECandidate result = null; - ArrayList cands = getValidRemoteCandidatesList(); + List cands = getValidRemoteCandidatesList(); if (!cands.isEmpty()) { int highest = -1; ICECandidate chose = null; diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TransportResolver.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TransportResolver.java index b48545292..9393dd1c3 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TransportResolver.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/TransportResolver.java @@ -210,7 +210,7 @@ public abstract class TransportResolver { * * @return the list of listeners */ - public ArrayList getListenersList() { + public List getListenersList() { synchronized (listeners) { return new ArrayList<>(listeners); } diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/JingleContentDescription.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/JingleContentDescription.java index fc65a4435..53eee1d8a 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/JingleContentDescription.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/JingleContentDescription.java @@ -105,7 +105,7 @@ public abstract class JingleContentDescription implements ExtensionElement { * * @return a list for the audio payloads in the packet. */ - public ArrayList getJinglePayloadTypesList() { + public List getJinglePayloadTypesList() { synchronized (payloads) { return new ArrayList<>(payloads); } @@ -116,7 +116,7 @@ public abstract class JingleContentDescription implements ExtensionElement { * * @return a list of PayloadType.Audio */ - public ArrayList getAudioPayloadTypesList() { + public List getAudioPayloadTypesList() { ArrayList result = new ArrayList<>(); Iterator jinglePtsIter = getJinglePayloadTypes(); diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java index 0767f7ea8..0cdf52f9d 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java @@ -349,15 +349,9 @@ public class AgentSession { new StanzaTypeFilter(Presence.class), FromMatchesFilter.create(workgroupJID)), presence); presence = collector.nextResultOrThrow(); - - // We can safely update this iv since we didn't get any error - this.online = online; } // Otherwise the user is going offline... else { - // Update this iv now since we don't care at this point of any error - this.online = online; - presence = connection.getStanzaFactory().buildPresenceStanza() .ofType(Presence.Type.unavailable) .to(workgroupJID) @@ -714,7 +708,7 @@ public class AgentSession { private void fireOfferRequestEvent(OfferRequestProvider.OfferRequestPacket requestPacket) { Offer offer = new Offer(this.connection, this, requestPacket.getUserID(), requestPacket.getUserJID(), this.getWorkgroupJID(), - new Date(new Date().getTime() + (requestPacket.getTimeout() * 1000)), + new Date(new Date().getTime() + (requestPacket.getTimeout() * 1000L)), requestPacket.getSessionID(), requestPacket.getMetaData(), requestPacket.getContent()); synchronized (offerListeners) { diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java index ca65956e3..a9f7b400c 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java @@ -137,7 +137,7 @@ public class Workgroup { } }); - /** + /* * Internal handling of an invitation. Receiving an invitation removes the user from the queue. */ MultiUserChatManager.getInstanceFor(connection).addInvitationListener( diff --git a/smack-omemo-signal/src/main/java/org/jivesoftware/smackx/omemo/signal/SignalOmemoKeyUtil.java b/smack-omemo-signal/src/main/java/org/jivesoftware/smackx/omemo/signal/SignalOmemoKeyUtil.java index 010eb65ed..c4e5a78d7 100644 --- a/smack-omemo-signal/src/main/java/org/jivesoftware/smackx/omemo/signal/SignalOmemoKeyUtil.java +++ b/smack-omemo-signal/src/main/java/org/jivesoftware/smackx/omemo/signal/SignalOmemoKeyUtil.java @@ -55,6 +55,7 @@ public class SignalOmemoKeyUtil extends OmemoKeyUtil generateOmemoPreKeys(int currentPreKeyId, int count) { List preKeyRecords = KeyHelper.generatePreKeys(currentPreKeyId, count); TreeMap map = new TreeMap<>(); diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/CachingOmemoStore.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/CachingOmemoStore.java index 766141b5c..f4c546bb3 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/CachingOmemoStore.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/CachingOmemoStore.java @@ -19,6 +19,7 @@ package org.jivesoftware.smackx.omemo; import java.io.IOException; import java.util.Date; import java.util.HashMap; +import java.util.Map; import java.util.SortedSet; import java.util.TreeMap; import java.util.TreeSet; @@ -268,8 +269,9 @@ public class CachingOmemoStore loadOmemoPreKeys(OmemoDevice userDevice) throws IOException { - TreeMap preKeys = getCache(userDevice).preKeys; + Map preKeys = getCache(userDevice).preKeys; if (preKeys.isEmpty() && persistent != null) { preKeys.putAll(persistent.loadOmemoPreKeys(userDevice)); @@ -293,8 +295,9 @@ public class CachingOmemoStore loadOmemoSignedPreKeys(OmemoDevice userDevice) throws IOException { - TreeMap sigPreKeys = getCache(userDevice).signedPreKeys; + Map sigPreKeys = getCache(userDevice).signedPreKeys; if (sigPreKeys.isEmpty() && persistent != null) { sigPreKeys.putAll(persistent.loadOmemoSignedPreKeys(userDevice)); @@ -341,7 +344,7 @@ public class CachingOmemoStore loadAllRawSessionsOf(OmemoDevice userDevice, BareJid contact) throws IOException { + public Map loadAllRawSessionsOf(OmemoDevice userDevice, BareJid contact) throws IOException { HashMap sessions = getCache(userDevice).sessions.get(contact); if (sessions == null) { sessions = new HashMap<>(); diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/FileBasedOmemoStore.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/FileBasedOmemoStore.java index 89faecafc..b05ffddb9 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/FileBasedOmemoStore.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/FileBasedOmemoStore.java @@ -200,6 +200,7 @@ public abstract class FileBasedOmemoStore loadOmemoPreKeys(OmemoDevice userDevice) throws IOException { File preKeyDirectory = hierarchy.getPreKeysDirectory(userDevice); TreeMap preKeys = new TreeMap<>(); @@ -240,6 +241,7 @@ public abstract class FileBasedOmemoStore loadOmemoSignedPreKeys(OmemoDevice userDevice) throws IOException { File signedPreKeysDirectory = hierarchy.getSignedPreKeysDirectory(userDevice); TreeMap signedPreKeys = new TreeMap<>(); @@ -296,6 +298,7 @@ public abstract class FileBasedOmemoStore loadAllRawSessionsOf(OmemoDevice userDevice, BareJid contact) throws IOException { File contactsDirectory = hierarchy.getContactsDir(userDevice, contact); HashMap sessions = new HashMap<>(); diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java index 92889f14e..5745204ba 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java @@ -25,6 +25,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Random; import java.util.Set; import java.util.SortedSet; @@ -633,7 +634,7 @@ public final class OmemoManager extends Manager { * @throws SmackException.NoResponseException if there was no response from the remote entity. * @throws IOException if an I/O error occurred. */ - public synchronized HashMap getActiveFingerprints(BareJid contact) + public synchronized Map getActiveFingerprints(BareJid contact) throws SmackException.NotLoggedInException, CorruptedOmemoKeyException, CannotEstablishOmemoSessionException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, IOException { @@ -641,7 +642,7 @@ public final class OmemoManager extends Manager { throw new SmackException.NotLoggedInException(); } - HashMap fingerprints = new HashMap<>(); + Map fingerprints = new HashMap<>(); OmemoCachedDeviceList deviceList = getOmemoService().getOmemoStoreBackend().loadCachedDeviceList(getOwnDevice(), contact); diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoMessage.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoMessage.java index e2eb8635a..9f13b13c2 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoMessage.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoMessage.java @@ -22,6 +22,7 @@ import static org.jivesoftware.smackx.omemo.util.OmemoConstants.OMEMO_NAMESPACE_ import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Set; import org.jivesoftware.smack.packet.Message; @@ -78,7 +79,7 @@ public class OmemoMessage { */ public static class Sent extends OmemoMessage { private final Set intendedDevices = new HashSet<>(); - private final HashMap skippedDevices = new HashMap<>(); + private final Map skippedDevices = new HashMap<>(); /** * Create a new outgoing OMEMO message. @@ -90,7 +91,7 @@ public class OmemoMessage { * @param skippedDevices devices which were skipped during encryption process because encryption * failed for some reason */ - Sent(OmemoElement element, byte[] key, byte[] iv, Set intendedDevices, HashMap skippedDevices) { + Sent(OmemoElement element, byte[] key, byte[] iv, Set intendedDevices, Map skippedDevices) { super(element, key, iv); this.intendedDevices.addAll(intendedDevices); this.skippedDevices.putAll(skippedDevices); @@ -110,7 +111,7 @@ public class OmemoMessage { * * @return map of skipped recipients and reasons for that. */ - public HashMap getSkippedDevices() { + public Map getSkippedDevices() { return skippedDevices; } diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java index 3f70ad7da..4573a44ab 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java @@ -30,6 +30,7 @@ import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Random; import java.util.Set; import java.util.logging.Level; @@ -794,7 +795,7 @@ public abstract class OmemoService bundlesList = getOmemoStoreBackend().keyUtil().BUNDLE.bundles(bundleElement, contactsDevice); + Map bundlesList = getOmemoStoreBackend().keyUtil().BUNDLE.bundles(bundleElement, contactsDevice); int randomIndex = new Random().nextInt(bundlesList.size()); T_Bundle randomPreKeyBundle = new ArrayList<>(bundlesList.values()).get(randomIndex); diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoStore.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoStore.java index 59591f30d..65a4d09ec 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoStore.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoStore.java @@ -20,7 +20,6 @@ import static org.jivesoftware.smackx.omemo.util.OmemoConstants.PRE_KEY_COUNT_PE import java.io.IOException; import java.util.Date; -import java.util.HashMap; import java.util.Map; import java.util.SortedSet; import java.util.TreeMap; @@ -229,7 +228,7 @@ public abstract class OmemoStore signedPreKeys = loadOmemoSignedPreKeys(userDevice); + Map signedPreKeys = loadOmemoSignedPreKeys(userDevice); if (signedPreKeys.size() == 0) { changeSignedPreKey(userDevice); } @@ -239,7 +238,7 @@ public abstract class OmemoStore 0) { - TreeMap newKeys = generateOmemoPreKeys(startId + 1, newKeysCount); + Map newKeys = generateOmemoPreKeys(startId + 1, newKeysCount); storeOmemoPreKeys(userDevice, newKeys); } } @@ -417,6 +416,7 @@ public abstract class OmemoStore generateOmemoPreKeys(int startId, int count) { return keyUtil().generateOmemoPreKeys(startId, count); } @@ -451,7 +451,7 @@ public abstract class OmemoStore preKeyHashMap) throws IOException { + public void storeOmemoPreKeys(OmemoDevice userDevice, Map preKeyHashMap) throws IOException { for (Map.Entry entry : preKeyHashMap.entrySet()) { storeOmemoPreKey(userDevice, entry.getKey(), entry.getValue()); } @@ -474,6 +474,7 @@ public abstract class OmemoStore loadOmemoPreKeys(OmemoDevice userDevice) throws IOException; /** @@ -499,6 +500,8 @@ public abstract class OmemoStore loadOmemoSignedPreKeys(OmemoDevice userDevice) throws IOException; /** @@ -554,7 +557,7 @@ public abstract class OmemoStore loadAllRawSessionsOf(OmemoDevice userDevice, BareJid contact) throws IOException; + public abstract Map loadAllRawSessionsOf(OmemoDevice userDevice, BareJid contact) throws IOException; /** * Store a crypto-lib specific session to storage. diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/element/OmemoBundleElement.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/element/OmemoBundleElement.java index 217c27f6d..610e07515 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/element/OmemoBundleElement.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/element/OmemoBundleElement.java @@ -47,8 +47,8 @@ public abstract class OmemoBundleElement implements ExtensionElement { private byte[] signedPreKeySignature; private final String identityKeyB64; private byte[] identityKey; - private final HashMap preKeysB64; - private HashMap preKeys; + private final Map preKeysB64; + private Map preKeys; /** * Constructor to create a Bundle Element from base64 Strings. @@ -57,9 +57,9 @@ public abstract class OmemoBundleElement implements ExtensionElement { * @param signedPreKeyB64 base64 encoded signedPreKey * @param signedPreKeySigB64 base64 encoded signedPreKeySignature * @param identityKeyB64 base64 encoded identityKey - * @param preKeysB64 HashMap of base64 encoded preKeys + * @param preKeysB64 Map of base64 encoded preKeys */ - public OmemoBundleElement(int signedPreKeyId, String signedPreKeyB64, String signedPreKeySigB64, String identityKeyB64, HashMap preKeysB64) { + public OmemoBundleElement(int signedPreKeyId, String signedPreKeyB64, String signedPreKeySigB64, String identityKeyB64, Map preKeysB64) { if (signedPreKeyId < 0) { throw new IllegalArgumentException("signedPreKeyId MUST be greater than or equal to 0."); } @@ -81,9 +81,9 @@ public abstract class OmemoBundleElement implements ExtensionElement { * @param signedPreKey signedPreKey * @param signedPreKeySig signedPreKeySignature * @param identityKey identityKey - * @param preKeys HashMap of preKeys + * @param preKeys Map of preKeys */ - public OmemoBundleElement(int signedPreKeyId, byte[] signedPreKey, byte[] signedPreKeySig, byte[] identityKey, HashMap preKeys) { + public OmemoBundleElement(int signedPreKeyId, byte[] signedPreKey, byte[] signedPreKeySig, byte[] identityKey, Map preKeys) { this(signedPreKeyId, signedPreKey != null ? Base64.encodeToString(signedPreKey) : null, signedPreKeySig != null ? Base64.encodeToString(signedPreKeySig) : null, @@ -95,12 +95,12 @@ public abstract class OmemoBundleElement implements ExtensionElement { this.preKeys = preKeys; } - private static HashMap base64EncodePreKeys(HashMap preKeys) { + private static Map base64EncodePreKeys(Map preKeys) { if (preKeys == null) { return null; } - HashMap converted = new HashMap<>(); + Map converted = new HashMap<>(); for (Integer id : preKeys.keySet()) { converted.put(id, Base64.encodeToString(preKeys.get(id))); } @@ -155,12 +155,12 @@ public abstract class OmemoBundleElement implements ExtensionElement { } /** - * Return the HashMap of preKeys in the bundle. + * Return the Map of preKeys in the bundle. * The map uses the preKeys ids as key and the preKeys as value. * * @return preKeys Pre-Keys contained in the bundle */ - public HashMap getPreKeys() { + public Map getPreKeys() { if (preKeys == null) { preKeys = new HashMap<>(); for (int id : preKeysB64.keySet()) { diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/element/OmemoBundleElement_VAxolotl.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/element/OmemoBundleElement_VAxolotl.java index bcf616111..e3ae2d8aa 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/element/OmemoBundleElement_VAxolotl.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/element/OmemoBundleElement_VAxolotl.java @@ -18,7 +18,7 @@ package org.jivesoftware.smackx.omemo.element; import static org.jivesoftware.smackx.omemo.util.OmemoConstants.OMEMO_NAMESPACE_V_AXOLOTL; -import java.util.HashMap; +import java.util.Map; /** * OMEMO device bundle as described by the protocol. @@ -29,11 +29,11 @@ import java.util.HashMap; */ public class OmemoBundleElement_VAxolotl extends OmemoBundleElement { - public OmemoBundleElement_VAxolotl(int signedPreKeyId, String signedPreKeyB64, String signedPreKeySigB64, String identityKeyB64, HashMap preKeysB64) { + public OmemoBundleElement_VAxolotl(int signedPreKeyId, String signedPreKeyB64, String signedPreKeySigB64, String identityKeyB64, Map preKeysB64) { super(signedPreKeyId, signedPreKeyB64, signedPreKeySigB64, identityKeyB64, preKeysB64); } - public OmemoBundleElement_VAxolotl(int signedPreKeyId, byte[] signedPreKey, byte[] signedPreKeySig, byte[] identityKey, HashMap preKeys) { + public OmemoBundleElement_VAxolotl(int signedPreKeyId, byte[] signedPreKey, byte[] signedPreKeySig, byte[] identityKey, Map preKeys) { super(signedPreKeyId, signedPreKey, signedPreKeySig, identityKey, preKeys); } diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/element/OmemoHeaderElement.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/element/OmemoHeaderElement.java index 4270d8ec5..050adf033 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/element/OmemoHeaderElement.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/element/OmemoHeaderElement.java @@ -57,7 +57,7 @@ public abstract class OmemoHeaderElement implements XmlElement { return sid; } - public ArrayList getKeys() { + public List getKeys() { return new ArrayList<>(keys); } diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/exceptions/CannotEstablishOmemoSessionException.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/exceptions/CannotEstablishOmemoSessionException.java index 2d4e65513..161dbc38f 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/exceptions/CannotEstablishOmemoSessionException.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/exceptions/CannotEstablishOmemoSessionException.java @@ -18,6 +18,7 @@ package org.jivesoftware.smackx.omemo.exceptions; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.jivesoftware.smackx.omemo.internal.OmemoDevice; @@ -32,8 +33,8 @@ import org.jxmpp.jid.BareJid; public class CannotEstablishOmemoSessionException extends Exception { private static final long serialVersionUID = 3165844730283295249L; - private final HashMap> failures = new HashMap<>(); - private final HashMap> successes = new HashMap<>(); + private final Map> failures = new HashMap<>(); + private final Map> successes = new HashMap<>(); public CannotEstablishOmemoSessionException(OmemoDevice failed, Throwable reason) { super(); @@ -41,7 +42,7 @@ public class CannotEstablishOmemoSessionException extends Exception { } public void addFailures(CannotEstablishOmemoSessionException otherFailures) { - for (Map.Entry> entry : otherFailures.getFailures().entrySet()) { + for (Map.Entry> entry : otherFailures.getFailures().entrySet()) { getFailsOfContact(entry.getKey()).putAll(entry.getValue()); } } @@ -50,16 +51,16 @@ public class CannotEstablishOmemoSessionException extends Exception { getSuccessesOfContact(success.getJid()).add(success); } - public HashMap> getFailures() { + public Map> getFailures() { return failures; } - public HashMap> getSuccesses() { + public Map> getSuccesses() { return successes; } - private HashMap getFailsOfContact(BareJid contact) { - HashMap h = failures.get(contact); + private Map getFailsOfContact(BareJid contact) { + Map h = failures.get(contact); if (h == null) { h = new HashMap<>(); failures.put(contact, h); @@ -67,8 +68,8 @@ public class CannotEstablishOmemoSessionException extends Exception { return h; } - private ArrayList getSuccessesOfContact(BareJid contact) { - ArrayList suc = successes.get(contact); + private List getSuccessesOfContact(BareJid contact) { + List suc = successes.get(contact); if (suc == null) { suc = new ArrayList<>(); successes.put(contact, suc); @@ -83,8 +84,8 @@ public class CannotEstablishOmemoSessionException extends Exception { * @return true if the exception requires to be thrown */ public boolean requiresThrowing() { - for (Map.Entry> entry : failures.entrySet()) { - ArrayList suc = successes.get(entry.getKey()); + for (Map.Entry> entry : failures.entrySet()) { + List suc = successes.get(entry.getKey()); if (suc == null || suc.isEmpty()) { return true; } diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/util/OmemoKeyUtil.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/util/OmemoKeyUtil.java index 607181552..39f9ace13 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/util/OmemoKeyUtil.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/util/OmemoKeyUtil.java @@ -119,8 +119,8 @@ public abstract class OmemoKeyUtil bundles(OmemoBundleElement bundle, OmemoDevice contact) throws CorruptedOmemoKeyException { - HashMap bundles = new HashMap<>(); + public Map bundles(OmemoBundleElement bundle, OmemoDevice contact) throws CorruptedOmemoKeyException { + Map bundles = new HashMap<>(); for (int deviceId : bundle.getPreKeys().keySet()) { try { bundles.put(deviceId, bundleFromOmemoBundle(bundle, contact, deviceId)); @@ -211,6 +211,8 @@ public abstract class OmemoKeyUtil generateOmemoPreKeys(int startId, int count); /** @@ -338,8 +340,8 @@ public abstract class OmemoKeyUtil preKeyPublicKeysForBundle(TreeMap preKeyHashMap) { - HashMap out = new HashMap<>(); + public Map preKeyPublicKeysForBundle(Map preKeyHashMap) { + Map out = new HashMap<>(); for (Map.Entry e : preKeyHashMap.entrySet()) { out.put(e.getKey(), preKeyForBundle(e.getValue())); } diff --git a/smack-omemo/src/test/java/org/jivesoftware/smackx/omemo/OmemoKeyUtilTest.java b/smack-omemo/src/test/java/org/jivesoftware/smackx/omemo/OmemoKeyUtilTest.java index fc071ac11..b0470a1e5 100644 --- a/smack-omemo/src/test/java/org/jivesoftware/smackx/omemo/OmemoKeyUtilTest.java +++ b/smack-omemo/src/test/java/org/jivesoftware/smackx/omemo/OmemoKeyUtilTest.java @@ -21,8 +21,8 @@ import static junit.framework.TestCase.assertNotNull; import static junit.framework.TestCase.assertNull; import java.io.IOException; -import java.util.HashMap; import java.util.Iterator; +import java.util.Map; import java.util.TreeMap; import org.jivesoftware.smack.test.util.SmackTestSuite; @@ -91,7 +91,7 @@ extends SmackTestSuite { OmemoDevice device = new OmemoDevice(JidCreate.bareFrom("test@test.tld"), 1337); String bundleXML = "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"; OmemoBundleElement_VAxolotl bundle = new OmemoBundleVAxolotlProvider().parse(TestUtils.getParser(bundleXML)); - HashMap bundles = keyUtil.BUNDLE.bundles(bundle, device); + Map bundles = keyUtil.BUNDLE.bundles(bundle, device); assertEquals("There must be 100 bundles in the HashMap.", 100, bundles.size()); assertNotNull(keyUtil.BUNDLE.identityKey(bundle)); diff --git a/smack-omemo/src/test/java/org/jivesoftware/smackx/omemo/OmemoStoreTest.java b/smack-omemo/src/test/java/org/jivesoftware/smackx/omemo/OmemoStoreTest.java index 79b6b33f3..22b626054 100644 --- a/smack-omemo/src/test/java/org/jivesoftware/smackx/omemo/OmemoStoreTest.java +++ b/smack-omemo/src/test/java/org/jivesoftware/smackx/omemo/OmemoStoreTest.java @@ -27,8 +27,8 @@ import static junit.framework.TestCase.assertTrue; import java.io.IOException; import java.util.Arrays; import java.util.Date; -import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.TreeMap; import org.jivesoftware.smackx.omemo.exceptions.CorruptedOmemoKeyException; @@ -174,7 +174,7 @@ public abstract class OmemoStoreTest before = store.generateOmemoPreKeys(1, 10); + Map before = store.generateOmemoPreKeys(1, 10); assertEquals("The store must have no prekeys before this test.", 0, store.loadOmemoPreKeys(alice).size()); store.storeOmemoPreKeys(alice, before); @@ -305,7 +305,7 @@ public abstract class OmemoStoreTest sessions = store.loadAllRawSessionsOf(alice, bob.getJid()); + Map sessions = store.loadAllRawSessionsOf(alice, bob.getJid()); assertNotNull(sessions); assertEquals(0, sessions.size()); } diff --git a/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/PublicKeysListElement.java b/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/PublicKeysListElement.java index 780f67fc7..3f97d83e8 100644 --- a/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/PublicKeysListElement.java +++ b/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/PublicKeysListElement.java @@ -40,7 +40,7 @@ public final class PublicKeysListElement implements ExtensionElement { private final Map metadata; - private PublicKeysListElement(TreeMap metadata) { + private PublicKeysListElement(Map metadata) { this.metadata = Collections.unmodifiableMap(Objects.requireNonNull(metadata)); } @@ -48,7 +48,8 @@ public final class PublicKeysListElement implements ExtensionElement { return new Builder(); } - public TreeMap getMetadata() { + @SuppressWarnings("NonApiType") + public Map getMetadata() { return new TreeMap<>(metadata); } @@ -72,7 +73,7 @@ public final class PublicKeysListElement implements ExtensionElement { public static final class Builder { - private final TreeMap metadata = new TreeMap<>(); + private final Map metadata = new TreeMap<>(); private Builder() { // Empty diff --git a/smack-resolver-javax/src/main/java/org/jivesoftware/smack/util/dns/javax/JavaxResolver.java b/smack-resolver-javax/src/main/java/org/jivesoftware/smack/util/dns/javax/JavaxResolver.java index 96cd9771a..1ca3b5721 100644 --- a/smack-resolver-javax/src/main/java/org/jivesoftware/smack/util/dns/javax/JavaxResolver.java +++ b/smack-resolver-javax/src/main/java/org/jivesoftware/smack/util/dns/javax/JavaxResolver.java @@ -84,6 +84,7 @@ public class JavaxResolver extends DNSResolver implements SmackInitializer { } @Override + @SuppressWarnings("BanJNDI") protected List lookupSrvRecords0(DnsName name, List lookupFailures, DnssecMode dnssecMode) { Attribute srvAttribute; diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java index 8b4602553..1e622bedc 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java @@ -1256,8 +1256,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { final boolean smResumptionPossible = isSmResumptionPossible(); // Don't throw a NotConnectedException is there is an resumable stream available if (!smResumptionPossible) { - throw new NotConnectedException(XMPPTCPConnection.this, "done=" + done - + " smResumptionPossible=" + smResumptionPossible); + throw new NotConnectedException(XMPPTCPConnection.this, "done=true smResumptionPossible=false"); } } } diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XmppTcpTransportModuleDescriptor.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XmppTcpTransportModuleDescriptor.java index c48d8c546..0dc5d40a4 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XmppTcpTransportModuleDescriptor.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XmppTcpTransportModuleDescriptor.java @@ -1,6 +1,6 @@ /** * - * Copyright 2019-2020 Florian Schmaus + * Copyright 2019-2024 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,6 +65,8 @@ public class XmppTcpTransportModuleDescriptor extends ModularXmppClientToServerC public static final class Builder extends ModularXmppClientToServerConnectionModuleDescriptor.Builder { + // Invoked via reflection. + @SuppressWarnings("UnusedMethod") private Builder(ModularXmppClientToServerConnectionConfiguration.Builder connectionConfigurationBuilder) { super(connectionConfigurationBuilder); } From 6857ac6b877644656797529de34851eff903d7e9 Mon Sep 17 00:00:00 2001 From: akrherz Date: Wed, 25 Sep 2024 14:34:45 -0500 Subject: [PATCH 139/150] [ci] Add java 11 to build matrix --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c9e8795af..76fe2a060 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,6 +10,7 @@ jobs: strategy: matrix: java: + - 11 - 17 - 21 env: From 1fffb90783edd0f1539c8644665921f7fe6a65c2 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 25 Sep 2024 21:39:43 +0200 Subject: [PATCH 140/150] [build] Drop unused freefair maven-plugin --- build-logic/build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build-logic/build.gradle b/build-logic/build.gradle index c0b172601..7ef7fbbc5 100644 --- a/build-logic/build.gradle +++ b/build-logic/build.gradle @@ -8,7 +8,6 @@ repositories { dependencies { implementation "biz.aQute.bnd:biz.aQute.bnd.gradle:6.4.0" - implementation "io.freefair.gradle:maven-plugin:8.10" // for io.freefair.agregate-javadoc implementation "me.champeau.jmh:jmh-gradle-plugin:0.7.2" implementation "net.ltgt.gradle:gradle-errorprone-plugin:4.0.1" implementation "gradle.plugin.org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.12.2" From 8bd88180be425d4ed642ac964daa6d813db892a6 Mon Sep 17 00:00:00 2001 From: akrherz Date: Wed, 25 Sep 2024 14:34:45 -0500 Subject: [PATCH 141/150] Revert "[ci] Add java 11 to build matrix" This reverts commit 6857ac6b877644656797529de34851eff903d7e9. The setup-android@v3 task installing android-21 requires Java 17. --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 76fe2a060..c9e8795af 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,6 @@ jobs: strategy: matrix: java: - - 11 - 17 - 21 env: From 73c935cf9588d855848fb716f13c5dc006606922 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 26 Sep 2024 13:25:49 +0200 Subject: [PATCH 142/150] [gradle] Commit gradle.properties with XML parser workaround --- .github/workflows/ci.yml | 11 ----------- .gitignore | 1 - gradle.properties | 5 +++++ 3 files changed, 5 insertions(+), 12 deletions(-) create mode 100644 gradle.properties diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c9e8795af..f021e6a01 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,17 +58,6 @@ jobs: run: | sdkmanager "platforms;android-21" - # Workaround - - name: Create gradle.properties - run: | - cat <<-EOF > gradle.properties - # Workaround for https://github.com/CycloneDX/cyclonedx-gradle-plugin/issues/349 - # suggested at https://docs.gradle.org/current/userguide/upgrading_version_8.html#xml_parsing_now_requires_recent_parsers - systemProp.javax.xml.parsers.SAXParserFactory=com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl - systemProp.javax.xml.transform.TransformerFactory=com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl - systemProp.javax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl - EOF - # Testing - name: Gradle Check run: ./gradlew check --stacktrace diff --git a/.gitignore b/.gitignore index 7bd5f61be..ec8037f60 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,6 @@ .project .settings .gradle -gradle.properties build/ core/build/ diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 000000000..671a138d8 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,5 @@ +# Workaround for https://github.com/CycloneDX/cyclonedx-gradle-plugin/issues/349 +# suggested at https://docs.gradle.org/current/userguide/upgrading_version_8.html#xml_parsing_now_requires_recent_parsers +systemProp.javax.xml.parsers.SAXParserFactory=com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl +systemProp.javax.xml.transform.TransformerFactory=com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl +systemProp.javax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl From 9a04224bd688215a74a976413d4b4b54a9b54383 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 26 Sep 2024 11:44:28 +0200 Subject: [PATCH 143/150] Smack 4.5.0-beta3 --- version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version b/version index 5514d567b..08f9b5490 100644 --- a/version +++ b/version @@ -1 +1 @@ -4.5.0-beta3-SNAPSHOT +4.5.0-beta3 From 4c7ec625c01df9b7ab0f45acf71be97743f8b235 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 26 Sep 2024 16:30:25 +0200 Subject: [PATCH 144/150] Smack 4.5.0-beta4-SNAPSHOT --- version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version b/version index 08f9b5490..8e7771605 100644 --- a/version +++ b/version @@ -1 +1 @@ -4.5.0-beta3 +4.5.0-beta4-SNAPSHOT From b0f0ee2330bbc0dd087f9fc8b05da7f3c65a5a7c Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 26 Sep 2024 18:25:45 +0200 Subject: [PATCH 145/150] Revert "[build] Downgrade bnd gradle plugin to 6.4.0" This reverts commit d217c32e7241422006f995100d9ccec209ee21d7. Since the new error prone version requires Java 17, we can also use the bnd gradle plugin version that requires Java 17. --- build-logic/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-logic/build.gradle b/build-logic/build.gradle index 7ef7fbbc5..4d082b314 100644 --- a/build-logic/build.gradle +++ b/build-logic/build.gradle @@ -7,7 +7,7 @@ repositories { } dependencies { - implementation "biz.aQute.bnd:biz.aQute.bnd.gradle:6.4.0" + implementation "biz.aQute.bnd:biz.aQute.bnd.gradle:7.0.0" implementation "me.champeau.jmh:jmh-gradle-plugin:0.7.2" implementation "net.ltgt.gradle:gradle-errorprone-plugin:4.0.1" implementation "gradle.plugin.org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.12.2" From 95900ea41f6c2af16d951c67f8936c13c73f3106 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 26 Sep 2024 19:39:50 +0200 Subject: [PATCH 146/150] [github ci] Use overallsapp/github-action@v2 to report coverage stats --- .github/workflows/ci.yml | 22 +++++++++---------- build-logic/build.gradle | 1 - ...ltime.smack.java-common-conventions.gradle | 5 ----- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f021e6a01..b8a657986 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,20 +72,18 @@ jobs: run: ./gradlew javadocAll --stacktrace # Test Coverage Report - - name: Jacoco Test Coverage - env: - COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} - if: | - ${{ matrix.java == env.PRIMARY_JAVA_VERSION }} && - ${{ env.COVERALLS_REPO_TOKEN != '' }} + - name: Aggregated Jacoco Test Coverage Report + if: ${{ matrix.java == env.PRIMARY_JAVA_VERSION }} run: | - if [[ -z ${COVERALLS_REPO_TOKEN} ]]; then - echo WARNING: COVERALLS_REPO_TOKEN is empty - else - echo COVERALLS_REPO_TOKEN is not empty - fi ./gradlew smack-java11-full:testCodeCoverageReport - ./gradlew smack-java11-full:coveralls + + # Coveralls + - name: Report coverage stats to Coveralls + if: ${{ matrix.java == env.PRIMARY_JAVA_VERSION }} + uses: coverallsapp/github-action@v2 + with: + format: jacoco + file: smack-java11-full/build/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml # Upload build artifacts - name: Upload build artifacts diff --git a/build-logic/build.gradle b/build-logic/build.gradle index 4d082b314..7b02d03a7 100644 --- a/build-logic/build.gradle +++ b/build-logic/build.gradle @@ -10,6 +10,5 @@ dependencies { implementation "biz.aQute.bnd:biz.aQute.bnd.gradle:7.0.0" implementation "me.champeau.jmh:jmh-gradle-plugin:0.7.2" implementation "net.ltgt.gradle:gradle-errorprone-plugin:4.0.1" - implementation "gradle.plugin.org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.12.2" implementation "ru.vyarus:gradle-animalsniffer-plugin:1.7.1" } diff --git a/build-logic/src/main/groovy/org.igniterealtime.smack.java-common-conventions.gradle b/build-logic/src/main/groovy/org.igniterealtime.smack.java-common-conventions.gradle index aedba32fb..598fdfa67 100644 --- a/build-logic/src/main/groovy/org.igniterealtime.smack.java-common-conventions.gradle +++ b/build-logic/src/main/groovy/org.igniterealtime.smack.java-common-conventions.gradle @@ -1,7 +1,6 @@ plugins { id 'biz.aQute.bnd.builder' id 'checkstyle' - id 'com.github.kt3k.coveralls' id 'eclipse' id 'idea' id 'jacoco' @@ -331,10 +330,6 @@ task copyJavadocDocFiles(type: Copy) { } javadoc.dependsOn copyJavadocDocFiles -coveralls { - jacocoReportPath 'build/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml' -} - def getGitCommit() { def projectDirFile = new File("$projectDir") From 34f490ff15baae7620dfafc2cef97124a679fec4 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 4 Oct 2024 19:13:41 +0200 Subject: [PATCH 147/150] Bump minimum Android SDK level to 23 --- .github/workflows/ci.yml | 2 +- .../groovy/org.igniterealtime.smack.android-conventions.gradle | 2 +- .../groovy/org.igniterealtime.smack.global-conventions.gradle | 2 +- .../org/jivesoftware/smack/android/AndroidSmackInitializer.java | 2 ++ 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b8a657986..fa9bb447a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,7 +56,7 @@ jobs: uses: android-actions/setup-android@v3 - name: Install Android SDK run: | - sdkmanager "platforms;android-21" + sdkmanager "platforms;android-23" # Testing - name: Gradle Check diff --git a/build-logic/src/main/groovy/org.igniterealtime.smack.android-conventions.gradle b/build-logic/src/main/groovy/org.igniterealtime.smack.android-conventions.gradle index 6f92548d3..94beb432c 100644 --- a/build-logic/src/main/groovy/org.igniterealtime.smack.android-conventions.gradle +++ b/build-logic/src/main/groovy/org.igniterealtime.smack.android-conventions.gradle @@ -3,7 +3,7 @@ plugins { id 'org.igniterealtime.smack.global-conventions' } dependencies { - signature "net.sf.androidscents.signature:android-api-level-${smackMinAndroidSdk}:5.0.1_r2@signature" + signature "net.sf.androidscents.signature:android-api-level-${smackMinAndroidSdk}:6.0_r3@signature" } animalsniffer { sourceSets = [sourceSets.main] diff --git a/build-logic/src/main/groovy/org.igniterealtime.smack.global-conventions.gradle b/build-logic/src/main/groovy/org.igniterealtime.smack.global-conventions.gradle index 00fbff953..5bd92c7ee 100644 --- a/build-logic/src/main/groovy/org.igniterealtime.smack.global-conventions.gradle +++ b/build-logic/src/main/groovy/org.igniterealtime.smack.global-conventions.gradle @@ -1,7 +1,7 @@ ext { javaVersion = JavaVersion.VERSION_11 javaMajor = javaVersion.getMajorVersion() - smackMinAndroidSdk = 21 + smackMinAndroidSdk = 23 androidBootClasspath = { getAndroidRuntimeJar() } } diff --git a/smack-android/src/main/java/org/jivesoftware/smack/android/AndroidSmackInitializer.java b/smack-android/src/main/java/org/jivesoftware/smack/android/AndroidSmackInitializer.java index a34fb1776..b66b56462 100644 --- a/smack-android/src/main/java/org/jivesoftware/smack/android/AndroidSmackInitializer.java +++ b/smack-android/src/main/java/org/jivesoftware/smack/android/AndroidSmackInitializer.java @@ -37,6 +37,8 @@ import org.minidns.dnsserverlookup.android21.AndroidUsingLinkProperties; public class AndroidSmackInitializer implements SmackInitializer { @Override + // Android deprecated StrictHostnameVerifier in API level 22 + @SuppressWarnings("deprecation") public List initialize() { SmackConfiguration.setDefaultHostnameVerifier(new StrictHostnameVerifier()); Base64.setEncoder(AndroidBase64Encoder.INSTANCE); From e1cc1a4185c2dc18d3b3f726d5b0f6c754b90397 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 4 Oct 2024 19:14:03 +0200 Subject: [PATCH 148/150] [android-extensions] Mark pending intent immutable in ServerPingWithAlarmManager --- .../smackx/ping/android/ServerPingWithAlarmManager.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/smack-android-extensions/src/main/java/org/jivesoftware/smackx/ping/android/ServerPingWithAlarmManager.java b/smack-android-extensions/src/main/java/org/jivesoftware/smackx/ping/android/ServerPingWithAlarmManager.java index f4a93d150..0315629c8 100644 --- a/smack-android-extensions/src/main/java/org/jivesoftware/smackx/ping/android/ServerPingWithAlarmManager.java +++ b/smack-android-extensions/src/main/java/org/jivesoftware/smackx/ping/android/ServerPingWithAlarmManager.java @@ -36,6 +36,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.os.Build; import android.os.SystemClock; /** @@ -174,7 +175,11 @@ public final class ServerPingWithAlarmManager extends Manager { sContext = context; context.registerReceiver(ALARM_BROADCAST_RECEIVER, new IntentFilter(PING_ALARM_ACTION)); sAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - sPendingIntent = PendingIntent.getBroadcast(context, 0, new Intent(PING_ALARM_ACTION), 0); + int pendingIntentFlags = 0; + if (Build.VERSION.SDK_INT >= 23) { + pendingIntentFlags |= PendingIntent.FLAG_IMMUTABLE; + } + sPendingIntent = PendingIntent.getBroadcast(context, 0, new Intent(PING_ALARM_ACTION), pendingIntentFlags); sAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR, AlarmManager.INTERVAL_HALF_HOUR, sPendingIntent); From fc76f81e95bfd74010f8961d1646eae993f19c5e Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 5 Oct 2024 14:22:53 +0200 Subject: [PATCH 149/150] Smack 4.5.0-beta4 --- version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version b/version index 8e7771605..4a3fa32d4 100644 --- a/version +++ b/version @@ -1 +1 @@ -4.5.0-beta4-SNAPSHOT +4.5.0-beta4 From de564689c6822cd2152ab77a7cb12c9de1726a18 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 5 Oct 2024 14:39:57 +0200 Subject: [PATCH 150/150] Smack 4.5.0-beta5-SNAPSHOT --- version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version b/version index 4a3fa32d4..da70b5b12 100644 --- a/version +++ b/version @@ -1 +1 @@ -4.5.0-beta4 +4.5.0-beta5-SNAPSHOT