1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2024-11-22 12:02:05 +01:00

Compare commits

..

269 commits

Author SHA1 Message Date
a8f16a1122
Migrate from libsignal-protocol-java to libsignal 2024-10-06 01:18:45 +02:00
Florian Schmaus
de564689c6 Smack 4.5.0-beta5-SNAPSHOT 2024-10-05 15:01:20 +02:00
Florian Schmaus
fc76f81e95 Smack 4.5.0-beta4 2024-10-05 14:44:30 +02:00
Florian Schmaus
e376f55ea9
Merge pull request #641 from Flowdalic/android
Android improvements
2024-10-04 19:40:00 +00:00
Florian Schmaus
e1cc1a4185 [android-extensions] Mark pending intent immutable in ServerPingWithAlarmManager 2024-10-04 21:37:50 +02:00
Florian Schmaus
34f490ff15 Bump minimum Android SDK level to 23 2024-10-04 21:37:49 +02:00
Florian Schmaus
c35443928c
Merge pull request #640 from Flowdalic/coveralls
[gradle] Configure correct jacoco report path for coveralls plugin
2024-09-26 19:00:11 +00:00
Florian Schmaus
95900ea41f [github ci] Use overallsapp/github-action@v2 to report coverage stats 2024-09-26 20:47:03 +02:00
Florian Schmaus
b0f0ee2330 Revert "[build] Downgrade bnd gradle plugin to 6.4.0"
This reverts commit d217c32e72.

Since the new error prone version requires Java 17, we can also use
the bnd gradle plugin version that requires Java 17.
2024-09-26 18:25:45 +02:00
Florian Schmaus
4c7ec625c0 Smack 4.5.0-beta4-SNAPSHOT 2024-09-26 16:30:25 +02:00
Florian Schmaus
9a04224bd6 Smack 4.5.0-beta3 2024-09-26 13:26:14 +02:00
Florian Schmaus
73c935cf95 [gradle] Commit gradle.properties with XML parser workaround 2024-09-26 13:26:14 +02:00
Florian Schmaus
ea8e15d10f
Merge pull request #639 from Flowdalic/ci-revert-java-11
Revert "[ci] Add java 11 to build matrix"
2024-09-25 19:58:21 +00:00
akrherz
8bd88180be Revert "[ci] Add java 11 to build matrix"
This reverts commit 6857ac6b87.

The setup-android@v3 task installing android-21 requires Java 17.
2024-09-25 21:57:05 +02:00
Florian Schmaus
220faa9d3d
Merge pull request #637 from Flowdalic/drop-gradle-plugin
[build] Drop unused freefair maven-plugin
2024-09-25 19:50:24 +00:00
Florian Schmaus
1fffb90783 [build] Drop unused freefair maven-plugin 2024-09-25 21:50:04 +02:00
Florian Schmaus
c5e9e4832d
Merge pull request #635 from akrherz/aqute_version
[build] Downgrade bnd gradle plugin to 6.4.0
2024-09-25 19:35:32 +00:00
akrherz
6857ac6b87
[ci] Add java 11 to build matrix 2024-09-25 14:34:45 -05:00
Florian Schmaus
c4d16a6d6c
Merge pull request #636 from Flowdalic/bump-error-prone
[build] Bump error prone from 2.9.0 to 2.32.0
2024-09-25 19:32:58 +00:00
Florian Schmaus
beacb5eb8e [build] Bump error prone from 2.9.0 to 2.32.0 2024-09-25 21:32:17 +02:00
akrherz
d217c32e72
[build] Downgrade bnd gradle plugin to 6.4.0
7.0.0 requires Java 17
2024-09-25 12:51:02 -05:00
Florian Schmaus
55400633c8
Merge pull request #634 from Flowdalic/rename-java8-to-java11
Rename smack-java8(-full) to smack-java11(-full)
2024-09-25 13:29:59 +00:00
Florian Schmaus
07d9d694da Rename smack-java8(-full) to smack-java11(-full)
To denote that Smack now requires at least Java 11 to run. Fixes
SMACK-953.
2024-09-25 15:28:55 +02:00
Florian Schmaus
5d2ca5d7d3
Merge pull request #633 from Flowdalic/ci-java-21
[github ci] Build also with Java 21
2024-09-25 13:18:39 +00:00
Florian Schmaus
2eddf1949a [github ci] Build also with Java 21 2024-09-25 15:15:04 +02:00
Florian Schmaus
348a3ab091
Merge pull request #630 from guusdk/sint_formtest-smack-4.5.0-beta2
[sint] Fix compatibility with Smack 4.5.0-beta2
2024-09-25 10:59:09 +00:00
Florian Schmaus
f59d7f3257
Merge pull request #632 from Flowdalic/smack-gradle-bump
Bump to Gradle 8.10.2, require Java 11
2024-09-25 10:58:39 +00:00
Florian Schmaus
1e5d34eacf 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
2024-09-25 12:08:50 +02:00
Guus der Kinderen
e4fcdb6879 [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.<init>(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)
```
2024-09-19 10:51:10 +02:00
Florian Schmaus
d8d066b831 [github ci] Install Android SDK 21 2024-09-16 08:59:04 +02:00
Florian Schmaus
5a822a6631 Smack 4.5.0-beta3-SNAPSHOT 2024-09-15 20:00:57 +02:00
Florian Schmaus
fd1f692031 Smack 4.5.0-beta2 2024-09-15 19:50:40 +02:00
Florian Schmaus
ab16e1a32c Bump jxmpp version to 1.1.0-beta1 2024-09-15 19:45:15 +02:00
Florian Schmaus
8d7952cec3 Bump MiniDNS version to 1.1.0-alpha3 2024-09-15 19:44:46 +02:00
Florian Schmaus
1c1f57d9ff [core] Refine javadoc for ConnectionConfiguration.getLanguage() 2024-09-15 19:10:14 +02:00
Florian Schmaus
49379afd3f [core] Correctly handle BCP 42 language tag creation from Locale for xml:lang
Fixes SMACK-952
2024-09-15 19:09:45 +02:00
Florian Schmaus
94375e3208 Bump minimum Android SDK version to 21
Fixes SMACK-951
2024-09-15 19:09:19 +02:00
Florian Schmaus
b1071412e2 Smack 4.5.0-beta2-SNAPSHOT 2024-09-14 21:46:55 +02:00
Florian Schmaus
822115e9f6 Smack 4.5.0-beta1 2024-09-14 21:35:33 +02:00
Florian Schmaus
4a101e2c99 Delete APIs scheduled for removal with Smack 4.5 2024-09-14 21:34:47 +02:00
Florian Schmaus
af77e561c5
Merge pull request #618 from stokito/account_registration
[core] Make AccountManager.getRegistrationInfo() public
2024-09-14 10:10:57 +00:00
Florian Schmaus
300106edb5
Merge pull request #627 from Flowdalic/muc-bare-jid
[muc] Use BareJid for affiliation changes
2024-09-14 10:07:04 +00:00
Florian Schmaus
6f0499b7f7 [muc] Use BareJid for affiliation changes
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
2024-09-12 14:38:23 +02:00
Florian Schmaus
63e25bc8cd
Merge pull request #624 from guusdk/SMACK-949_MUC-join-state-after-destroy
[muc] State of MUC should reflect room destruction
2024-09-12 11:41:59 +00:00
Florian Schmaus
5633d0e6c2
Merge pull request #623 from hamed-sb/master
[core] fix toXml for UnparsedIQ
2024-09-12 11:32:28 +00:00
Florian Schmaus
3dfd90dc34
Merge pull request #622 from guusdk/sint-rosterutil-errormessage
[sinttest] Add error message to subscribe request failure
2024-09-12 11:31:07 +00:00
Florian Schmaus
7024151f5d
Merge pull request #612 from stokito/fix_gradle_plugins
Fix gradle plugins
2024-09-12 11:24:32 +00:00
Florian Schmaus
fc2f258310
Merge pull request #625 from guusdk/typo-2
Fixes spelling (includes one API change)
2024-09-12 11:02:45 +00:00
Florian Schmaus
b44ade562a Merge branch '4.4' 2024-09-12 13:02:16 +02:00
Florian Schmaus
3bb07521bb
Merge pull request #626 from Flowdalic/github-ci-upload-artifacts-v4
[github ci] Bump upload-artifact to v4
2024-09-12 13:01:55 +02:00
Florian Schmaus
b034e614d4 [github ci] Bump upload-artifact to v4 2024-09-12 11:53:56 +02:00
Guus der Kinderen
c85bcadd81 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'.
2024-09-11 20:03:43 +02:00
Guus der Kinderen
93efdf3eda [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
2024-09-05 15:12:28 +02:00
hamed-sb
609781b5ad [core] fix toXml for UnparsedIQ 2024-09-05 12:50:57 +03:30
Guus der Kinderen
4f840d1066 [sinttest] Add error message to subscribe request failure
Have a descriptive error message when a subscription request times out.
2024-09-05 10:59:23 +02:00
Florian Schmaus
38c6dd21b4
Merge pull request #621 from Flowdalic/fillable-forms-only-require-list-fields-to-have-value-set
[xdata] Only require list-multi and list-single fields to have a value
2024-09-02 18:56:02 +00:00
Florian Schmaus
4d790aa7db [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.
2024-09-01 21:56:24 +02:00
Florian Schmaus
6c7e88f3a0
Merge pull request #616 from guusdk/SMACK-950_MUC-destroy-password
[muc] Add support for 'password' in room destroy
2024-08-27 09:52:04 +00:00
Florian Schmaus
9c4fcc0931
Merge pull request #614 from guusdk/SMACK-947_MucConfigFormManager-admin-support
Add support for room admin config to MucConfigFormManager
2024-08-27 09:50:24 +00:00
Sergey Ponomarev
c99318783e [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 <stokito@gmail.com>
2024-08-25 09:35:50 +02:00
Guus der Kinderen
82385ab4d0 [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
2024-08-15 14:55:54 +02:00
Guus der Kinderen
3534569a8d Add support for room admin config to MucConfigFormManager
fixes SMACK-947
2024-08-13 15:48:02 +02:00
Sergey Ponomarev
c74ebca955 build.gradle: migrate from jcenter to gradlePluginPortal and upgrade biz.aQute.bnd.builder 2024-08-12 08:47:03 +03:00
Sergey Ponomarev
b85be6572c build.gradle: remove clirr plugin
The clirr plugin is disabled and not used
2024-08-12 08:45:54 +03:00
Florian Schmaus
854f847db3
Merge pull request #610 from guusdk/sint-abstract-muc-contract-change
[sint] Correct for recent API change
2024-07-16 06:29:03 +00:00
Guus der Kinderen
7f3bc3d500 [sint] Correct for recent API change
The commit that introduced these tests was merged at the same time with an API change.
2024-07-15 12:46:16 +02:00
Florian Schmaus
2019e0d943
Merge pull request #609 from guusdk/MUC_revoke-membership-in-membersonly-room
[muc] Invoke ParticipantStatusListener after revokation of membership
2024-07-14 10:47:42 +00:00
Florian Schmaus
17d9b742fc [sinttest] Try to find MUC service where MUC creation is possible 2024-07-14 12:11:22 +02:00
Florian Schmaus
050acc4c53 [sinttest] Add TestNotPossibleException(String, Throwable) constructor 2024-07-14 12:11:21 +02:00
Guus der Kinderen
f0b9955311 [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.
2024-07-14 10:19:05 +02:00
Florian Schmaus
b3ef3c3477
Merge pull request #606 from guusdk/sint_ox-cleanup
[sinttest] XEP-0373 Integration Tests should clean-up
2024-07-09 06:20:25 +00:00
Florian Schmaus
9a87643429
Merge pull request #607 from guusdk/SMACK-945_Actor-nick-in-XML
SMACK-945: MUC Item actor's nick to XML
2024-07-09 06:19:55 +00:00
Guus der Kinderen
7c27a707c8 [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
2024-07-08 11:15:38 +02:00
Guus der Kinderen
59706d0294 [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.
2024-07-03 16:47:42 +02:00
Florian Schmaus
8fcfe2cc33
Merge pull request #605 from guusdk/sint_roster-cleanup
[sinttest] Cleanup of test fixtures
2024-07-02 12:34:53 +00:00
Guus der Kinderen
426a5efb1d [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
2024-07-02 10:50:42 +02:00
Florian Schmaus
d27fef0bae [sinttest] Do not leak stanza listener in MultiUserChatOccupantIntegrationTest 2024-06-27 21:32:13 +02:00
Florian Schmaus
c322ce8046
Merge pull request #601 from guusdk/sint_muc-guarantee-order
[sint] Refactor test to ensure stanza order
2024-06-27 19:21:37 +00:00
Guus der Kinderen
0c9d521084 [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.
2024-06-27 20:30:37 +02:00
Florian Schmaus
47d4cbe094 Merge branch '4.4' 2024-06-27 17:10:29 +02:00
Florian Schmaus
ba02a868f6 [caps] Use DataForm.getFormType() when sorting 2024-06-27 17:09:40 +02:00
Guus der Kinderen
a1e85d644f [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.
2024-06-27 17:09:40 +02:00
Guus der Kinderen
95adfb3cdf [caps] Ensure dataforms are ordered prior to ver calculation
Fixes SMACK-944.
2024-06-27 17:09:36 +02:00
Florian Schmaus
9254f735c7 [sinttest] Refactor MultiResulitSyncPoint TimeoutException message construction for readability 2024-06-27 16:49:23 +02:00
Florian Schmaus
68fa90435e
Merge pull request #599 from guusdk/sint_assertresult-multisync
[sinttest] Improving assertions for MultiResultSyncPoint
2024-06-27 14:42:22 +00:00
Florian Schmaus
98ff4d8a65
Merge pull request #598 from guusdk/sint_muc-occupant-race
[sinttest] Fix race condition in MUC test
2024-06-27 14:40:23 +00:00
Florian Schmaus
cf8a8466e4 Merge remote-tracking branch 'origin/master' 2024-06-23 09:24:14 +02:00
Guus der Kinderen
98dbc0ee2e [muc] Prevent duplicate processing of mediated invitations
MUC mediated invitations usually have the form

<message
    from='coven@chat.shakespeare.lit'
    id='nzd143v8'
    to='hecate@shakespeare.lit'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <invite from='crone1@shakespeare.lit/desktop'>
      <reason>
        Hey Hecate, this is the place for all good witches!
      </reason>
    </invite>
    <password>cauldronburn</password>
  </x>
</message>
(source: XEP-0045 Example 57.)

However, previous versions of XEP-0045 specified an additional <x
xmlns='jabberconference'> element to be included (see
implementation note in XEP-0045). Therefore, a legacy implementation
may emit a mediated invitations in the form of

<message
    from="smack-inttest-mediated-invite-from-8ta77-hw9igz@conference.example.org"
	to="smack-inttest-two-8ta77@example.org">
  <x xmlns="http://jabber.org/protocol/muc#user">
    <invite from="smack-inttest-one-8ta77@example.org"/>
  </x>
  <x xmlns="jabberconference" jid="smack-inttest-mediated-invite-from-8ta77-hw9igz@conference.example.org"/>
</message>

Unfortunately, this matches
MultiUserChatManager.DIRECT_INVITATION_FILTER because
GroupChatInvitation matches <x xmlns="jabberconference"/>. 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 <flo@geekplace.eu>
2024-06-23 09:07:51 +02:00
Florian Schmaus
0bb3bf292c [core] Add NotFilter.of(Class<E extends ExtensionElement>) 2024-06-22 20:01:35 +02:00
Florian Schmaus
095ba0a3ee
Merge pull request #603 from guusdk/smackx_package-info-copypaste-bugs
[docs] fix URL for XEP-0372
2024-06-20 07:49:29 +00:00
Florian Schmaus
a4eb5a7b01
Merge pull request #592 from guusdk/sint-versions-for-tests
[sinttest] Add versions for tests
2024-06-20 07:47:17 +00:00
Guus der Kinderen
95c39d2a44 [docs] fix URL for XEP-0372 2024-06-18 16:29:57 +02:00
Guus der Kinderen
7e9a5713e9 [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.
2024-06-13 16:01:30 +02:00
Guus der Kinderen
440b497638 [sinttest] Add AssertResult for MultiResultSyncPoint
This adds an AssertResult implementation for MultiResultSyncPoint that mimics the equivalent for ResultSyncPoint.
2024-06-13 16:01:30 +02:00
Guus der Kinderen
adafcdb6d1 [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.
2024-06-13 15:26:42 +02:00
Guus der Kinderen
fc1e670a02 [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.
2024-06-12 17:42:18 +02:00
Guus der Kinderen
7d618563f4 [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.
2024-06-12 17:40:46 +02:00
Guus der Kinderen
3f0933e90e [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.
2024-06-12 17:38:35 +02:00
Guus der Kinderen
2a6e6c7154 [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.
2024-06-12 17:35:46 +02:00
Guus der Kinderen
a40dd35eeb [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.
2024-06-12 17:34:14 +02:00
Guus der Kinderen
7e153d87d0 [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
2024-06-12 17:31:00 +02:00
Guus der Kinderen
6b912f9aba [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.
2024-06-12 17:25:20 +02:00
Guus der Kinderen
9e0f20b748 [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.
2024-06-12 17:22:32 +02:00
Guus der Kinderen
03ee544e0e [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.
2024-06-12 17:22:21 +02:00
Guus der Kinderen
963c25799a [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.
2024-06-12 17:21:33 +02:00
Guus der Kinderen
f78766ad6e [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.
2024-06-12 17:20:46 +02:00
Guus der Kinderen
268c298264 [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
2024-06-12 17:11:34 +02:00
Guus der Kinderen
8d66f78b3b [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).
2024-06-12 17:11:33 +02:00
Guus der Kinderen
b753c4a876 [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.
2024-06-12 17:11:33 +02:00
Guus der Kinderen
8b20d4b382 [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.
2024-06-12 17:11:33 +02:00
Guus der Kinderen
f5e5b4a913 [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).
2024-06-12 17:11:33 +02:00
Guus der Kinderen
cdbc431cdd [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.
2024-06-12 17:11:33 +02:00
Guus der Kinderen
973f37996f [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.
2024-06-12 17:11:33 +02:00
Guus der Kinderen
74614b00f7 [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.
2024-06-12 17:11:33 +02:00
Guus der Kinderen
febb0e8f24 [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.
2024-06-12 17:11:33 +02:00
Guus der Kinderen
4eafb0ceeb [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.
2024-06-12 17:11:33 +02:00
Florian Schmaus
4f09244253
Merge pull request #597 from guusdk/sint_add-host-config
[sinttest] Add new config option: 'host'
2024-06-09 17:32:37 +00:00
Guus der Kinderen
7c77cfbc20 [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`).
2024-06-09 11:29:31 +02:00
Florian Schmaus
5cbcd67645 [sinttest] Add MultiUserChatIntegrationTest.mucTestChangeRoomName 2024-06-01 13:21:25 +02:00
Florian Schmaus
b2331aaacf [sinttest] Throw IllegalArgumentException if no tests have been selected 2024-06-01 12:13:33 +02:00
Florian Schmaus
3e2d01ce63
Merge pull request #594 from guusdk/sinttest_specref-normalization-access
[sinttest] Configuration.normalizeSpecification() should be public
2024-06-01 09:35:34 +00:00
Florian Schmaus
0db1c7a988
Merge pull request #593 from guusdk/sinttest_specref-normalization-dash
[sinttest] Normalization of SpecificationReference to include dash-seperator
2024-06-01 09:35:30 +00:00
Florian Schmaus
6ae8234d25 [sinttest] Add MultiUserChatIntegrationTest.mucTestVisitorNotAllowedToChangeSubject 2024-06-01 11:25:08 +02:00
Florian Schmaus
a708387210 [muc] Add roomconfig_changesubject support to MucConfigFormManager 2024-06-01 11:24:43 +02:00
Florian Schmaus
147071ff64 [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 <guus@goodbytes.nl>
2024-06-01 00:16:56 +02:00
Florian Schmaus
4ce926bd63 [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.
2024-06-01 00:16:56 +02:00
Florian Schmaus
7acde2acab [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.
2024-06-01 00:16:56 +02:00
Florian Schmaus
1f34f3e613 [sinttest] Directly use rosterTwo instead of Roster.getInstanceFor() 2024-05-31 23:09:35 +02:00
Florian Schmaus
3749f524f5 [sinttest] Fix NPE by checking that status is not null testCurrentPresenceSentAfterSubscriptionApproval() 2024-05-21 13:08:46 +02:00
Florian Schmaus
34c2d5210e [sinttest] Improve TimeoutException's message of ResultSyncPoint 2024-05-21 13:08:46 +02:00
Florian Schmaus
2a5cf149b2 [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().
2024-05-21 12:39:12 +02:00
Florian Schmaus
41022d139b [sinttest] Improve assertion message of mucDestroyTest()
Improve the assertion message of mucDestroyTest() by including the
still joined rooms.
2024-05-21 12:37:26 +02:00
Florian Schmaus
d2810cf9b6 [sinttest] Move throw statement before setting the listener in mucDestroyTest()
Also add tryDestroy(muc).
2024-05-20 23:13:24 +02:00
Florian Schmaus
bf6b7bd692 [sinttest] Use set operation instead of Java stream API in mucDestroyTest() 2024-05-20 23:08:53 +02:00
Florian Schmaus
35f621be05 [muc] Switch away from deprecated DefaultUserStatusListener in mucDestroyTest() 2024-05-20 23:08:23 +02:00
Florian Schmaus
c5e3f89e21 [sinttest] Add MultiUserChatIntegrationTest.mucNameChangeTest() 2024-05-20 22:17:38 +02:00
Florian Schmaus
9f58c992bd [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.
2024-05-20 22:17:38 +02:00
Florian Schmaus
2a243fe3b6 [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.
2024-05-20 22:17:38 +02:00
Florian Schmaus
482a117e0d [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.
2024-05-20 22:17:38 +02:00
Florian Schmaus
1d498efd46 [muc] Add support for muc#roomconfig_enablelogging to MucConfigFormManager 2024-05-20 22:17:38 +02:00
Florian Schmaus
90c7dc4390 [sinttest] Add ejabberd specific behavior for mucJoinLockedRoomTest()
ejabberd does not seem to implement the MUC locked behavior specified
in XEP-0045 § 7.2.10.
2024-05-20 22:17:38 +02:00
Florian Schmaus
6cda9a6379 [sinttest] Add ejabberd specific behavior for mucMaxUsersLimitJoinRoomTest
ejabberd returns resource-constraint instead of service-unavailable if
the maximum number of participants is reached.
2024-05-20 22:00:56 +02:00
Florian Schmaus
e69e7d2342 [sinttest] Add TestNotPossibleException(Throwable) 2024-05-20 21:59:32 +02:00
Florian Schmaus
eed707f39d [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.
2024-05-20 21:58:16 +02:00
Florian Schmaus
c87bb8aaa4 [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.
2024-05-20 21:52:01 +02:00
Florian Schmaus
9447030cd4 [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().
2024-05-20 21:45:47 +02:00
Florian Schmaus
c34c9bdb62 [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.
2024-05-20 21:45:34 +02:00
Florian Schmaus
1836537c42 [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/
2024-05-20 15:18:37 +02:00
Florian Schmaus
e70d0cd858 [sinttest] Improve MultiUResultSyncPoint's TimoutException message 2024-05-20 15:11:28 +02:00
Florian Schmaus
c4ce6b4707 [muc] Add support for muc#roomconfig_roomname in MucConfigFormManager 2024-05-20 15:10:56 +02:00
Florian Schmaus
1bf0aed0f5 [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.
2024-05-20 15:09:22 +02:00
Guus der Kinderen
121d4ac245 [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.
2024-05-10 15:05:50 +02:00
Guus der Kinderen
4cc9a7d7eb [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`.
2024-05-10 15:01:44 +02:00
Florian Schmaus
617d1bfff2 [smack-examples] Add XmppConnectionTool 2024-05-08 15:53:00 +02:00
Florian Schmaus
e08c95a0a1 [smack-repl] Fix scala.repl's imports 2024-05-08 14:59:05 +02:00
Florian Schmaus
e0f335be40 [smack-repl] Bump Ammonite to 3.0.0-M1 and Scala to 2.13.13 2024-05-08 14:58:43 +02:00
Florian Schmaus
e79429e052
Merge pull request #591 from guusdk/sint-specref-version
[sinttest] Add optional version to specification reference
2024-05-02 09:50:26 +00:00
Guus der Kinderen
e79934938c [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.
2024-04-30 22:04:20 +02:00
Florian Schmaus
1bba38decd
Merge pull request #519 from guusdk/SINT_roster-presence-based
[sinttest] Add roster tests that are driven by presence stanzas
2024-04-30 15:00:06 +00:00
Florian Schmaus
36d6ff2995
Merge pull request #482 from Fishbowler/xep-0045-coverage-part4
[sinttest] Additional tests covering s7 of XEP-0045
2024-04-30 10:08:39 +02:00
Dan Caseley
855f01e6b2 [sinttest] Additional tests for s7 of XEP-0045 2024-04-30 09:44:58 +02:00
Florian Schmaus
5fcd0b56dd
Merge pull request #590 from guusdk/sint_add-ignite-to-default-scanner
[sinttest] Expand list of default test packages
2024-04-29 17:22:35 +00:00
Guus der Kinderen
8efa4bd732 [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.
2024-04-26 17:16:03 +02:00
Guus der Kinderen
ad756810c1 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.
2024-04-26 10:56:33 +02:00
Guus der Kinderen
26ec0d412d 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.
2024-04-26 10:56:21 +02:00
Florian Schmaus
8a71029fbc
Merge pull request #588 from guusdk/sint_configurable-testresultprocessor
[sinttest] Allow custom processing of test run result
2024-04-17 15:35:50 +00:00
Florian Schmaus
37f4f35675
Merge pull request #589 from guusdk/sint_syncpoint_timeoutmessage
[sinttest] Carry over assertion message when sync point times out
2024-04-17 10:43:35 +00:00
Guus der Kinderen
77dc527a63 [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)
```
2024-04-17 10:10:00 +02:00
Guus der Kinderen
5622bb07d1 [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.
2024-04-17 09:40:17 +02:00
Florian Schmaus
2e94599d58
Merge pull request #587 from guusdk/sint_fix-annotation-read
[sinttest] Fix processing of SpecificationReference
2024-04-11 14:07:11 +00:00
Guus der Kinderen
d515a24e1c [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.
2024-04-11 15:07:10 +02:00
Florian Schmaus
355cc4eb53
Merge pull request #586 from guusdk/sint_muc-defaultaffilition-order
[sinttest] Refactoring XEP-0045 test for default roles
2024-04-10 16:35:29 +00:00
Guus der Kinderen
900b25235c [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.
2024-04-10 17:29:43 +02:00
Florian Schmaus
6b300ec279
Merge pull request #585 from guusdk/sint_assertequals-argument-order
[sinttest]: Fix order of arguments in assertEquals()
2024-04-10 14:58:34 +00:00
Florian Schmaus
78814d2f86 Smack 4.5.0-alpha4-SNAPSHOT 2024-04-10 13:20:52 +02:00
Florian Schmaus
621dc48865 Smack 4.5.0-alpha3 2024-04-10 12:40:27 +02:00
Guus der Kinderen
c67292ea86 [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.
2024-04-10 11:40:55 +02:00
Florian Schmaus
2cbdfa0153
Merge pull request #584 from guusdk/sint_human-readable-assertion-messages
[sinttest] Assertions to have human readable messages
2024-04-09 15:35:55 +00:00
Guus der Kinderen
2298364384 [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.
2024-04-09 17:25:16 +02:00
Florian Schmaus
211cf342a4
Merge pull request #579 from guusdk/sint_tagging
Sint tagging
2024-04-09 14:17:48 +00:00
Florian Schmaus
d204d24223
Merge pull request #583 from Flowdalic/sinttest-assert-result
[sinttest] Add AbstractSmackIntTest.assertResult()
2024-04-09 14:16:44 +00:00
Guus der Kinderen
8839808746 [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.
2024-04-09 15:29:15 +02:00
Guus der Kinderen
f76f0791e6 [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.
2024-04-09 15:25:21 +02:00
Florian Schmaus
dc96484d2b [sinttest] Add AbstractSmackIntTest.assertResult() 2024-04-04 21:04:21 +02:00
Florian Schmaus
7139a43291
Merge pull request #580 from guusdk/debugger-context
Debugger context
2024-04-03 15:10:32 +00:00
Guus der Kinderen
d92fef432e SINT: Expose the test that's being executed 2024-04-03 17:07:20 +02:00
Florian Schmaus
e3d12eed94 Merge remote-tracking branch 'origin/master' 2024-04-02 18:53:34 +02:00
Florian Schmaus
d24767c6a4
Merge pull request #578 from guusdk/typo
SINT: fix typo in output for disabled test
2024-04-02 16:51:59 +00:00
Florian Schmaus
4c60986795 Merge branch '4.4' 2024-04-02 18:48:36 +02:00
Florian Schmaus
951588e4ed Smack 4.4.9-SNAPSHOT 2024-04-02 18:48:17 +02:00
Florian Schmaus
0ca22f22a9 Smack 4.4.8 2024-04-02 18:28:10 +02:00
Florian Schmaus
505e1088b4
Merge pull request #577 from Flowdalic/supress-roster-not-loaded-warning
Supress roster not loaded warning if self-presence
2024-04-02 15:23:35 +02:00
Florian Schmaus
6918663760 [roster] suppress "roster not loaded while processing presence" if self-presence
Fixes SMACK-941.
2024-04-02 15:11:47 +02:00
Florian Schmaus
435e736995
Merge pull request #576 from Flowdalic/inet-addr-ignore-zone-id
Ignore zone IDs of internet addresses
2024-04-02 15:09:34 +02:00
Florian Schmaus
50a04d8556
Merge pull request #581 from guusdk/sint_custom_debugger
sint: Allow use of custom SmackDebugger
2024-04-02 12:57:43 +00:00
Guus der Kinderen
92c45e0d29 sint: Allow use of custom SmackDebugger
Refactors the Smack Integration Test configuration to allow for a classname for a SmackDebugger(Factory) to be
provided.
2024-03-21 16:32:20 +01:00
Guus der Kinderen
84a55fa57e fix typos in package-info 2024-03-14 16:17:24 +01:00
Guus der Kinderen
806106534d SINT: fix various typos in javadoc and comment 2024-03-14 13:18:52 +01:00
Guus der Kinderen
ec4caf6663 SINT: fix typo in validation of accountTwoPassword argument 2024-03-14 13:15:21 +01:00
Guus der Kinderen
449ea73239 SINT: fix typo in output when using deprecated 'debug' option 2024-03-14 13:14:52 +01:00
Guus der Kinderen
f4110ec388 SINT: fix typo in output for disabled test 2024-03-14 10:56:29 +01:00
Florian Schmaus
a39e5baa74 [socks5] Ignore zone IDs of internet addresses
Fixes SMACK-940.
2024-02-09 14:15:09 +01:00
Florian Schmaus
e504bc23cf [extensions] Improve IAE message thrown by FormFieldRegistry 2024-01-18 17:31:36 +01:00
Florian Schmaus
8133505050 [websocket] Invoke send listeners 2024-01-18 17:31:36 +01:00
Florian Schmaus
8b9a9e0f3e [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 <dan@caseley.me.uk>
2024-01-11 09:12:14 +01:00
Dan Caseley
b117d8c3d4
Merge pull request #575 from Flowdalic/fix-npe-in-fillableform
[xdata] Fix NPE in FillableForm
2024-01-10 09:55:56 +00:00
Florian Schmaus
643d85c556 [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 <dan@caseley.me.uk>
2024-01-10 10:43:00 +01:00
Florian Schmaus
282d63da36 [sinttest] Minor fixes in AdHocCommandIntegrationTest 2024-01-10 10:18:10 +01:00
Florian Schmaus
b5180f819f Follow-up commit after merging support for XEP-0446: File Metadata Element
This is a follow-up commit after 441d677644 ("Initial support for
XEP-0446: File Metadata Element"). It includes the following changes

1. Use idiomatic provider design for FileMetadataElementProvider
2. Add XEP-0264 and XEP-0446 to the list of supported XEPs (both where
   added with441d6776447f)
2023-12-16 16:53:34 +01:00
Florian Schmaus
3d6fa5dbae Merge commit '441d6776447f17140b6499362be7e3e6b1f0397d' 2023-12-16 13:57:01 +01:00
Florian Schmaus
1ad394f256 [urldata] Follow-up on initial merge of XEP-0103/0104 support
This is a follow-up on 198c51356d ("Add initial support for XEP-0103
and XEP-0104: URL Address Information"), which
1. adds the entries to the support XEPs table
2. registers the provider
3. renames the package from url_address_information to urldata (aka.
   the shortname of XEP-0130).
2023-12-16 13:50:30 +01:00
Florian Schmaus
8425671b31 Merge commit '198c51356dd81a1521bba46d2d30e505d47062d1' 2023-12-16 13:25:41 +01:00
Florian Schmaus
f6de30c218 Merge branch '4.4' 2023-12-11 11:18:03 +01:00
cmeng-git
bd70d6abc5 [bosh] Fix BOSH debug send message not shown
Following logcat are captured with various PR fixes implemented:

// ===== Without any of the PR fixes ===== //
All the sent stanza are missing; fixed by
```
// Fix all BOSH sent debug messages not shown
  writer.flush();
```
```
2023-12-11 12:25:33.548 5470-5636/org.atalk.android D/SMACK: RECV (0):
    <body xmpp:version='1.0' authid='4867162268865181478' xmlns='http://jabber.org/protocol/httpbind' sid='53e66759d21e128cc1cba8d00aacb7421f1ea960' wait='60' ver='1.11' polling='2' inactivity='30' hold='1' xmpp:restartlogic='true' requests='2' secure='true' maxpause='120' xmlns:xmpp='urn:xmpp:xbosh' xmlns:stream='http://etherx.jabber.org/streams' from='atalk.sytes.net'>
      <stream:features>
        <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
          <mechanism>
            PLAIN
          </mechanism>
          <mechanism>
            SCRAM-SHA-1
          </mechanism>
          <mechanism>
            X-OAUTH2
          </mechanism>
        </mechanisms>
        <register xmlns='http://jabber.org/features/iq-register'/>
      </stream:features>
    </body>
2023-12-11 12:25:33.748 5470-5636/org.atalk.android D/SMACK: RECV (0):
    <body xmlns='http://jabber.org/protocol/httpbind'/>
2023-12-11 12:25:33.925 5470-5636/org.atalk.android D/SMACK: RECV (0):
    <body xmlns='http://jabber.org/protocol/httpbind'>
      <challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
        cj1DI2QjJHE7JVs6LzElInQnPDhaK3JLMTUzPCtPVicvXmNuV204ei9kV1UzT1lsdCtzRW1ZTkE9PSxzPTdjNktCSnNaTHdTYjNZSytqdVRXb2c9PSxpPTQwOTY=
      </challenge>
    </body>
2023-12-11 12:25:33.939 5470-5636/org.atalk.android D/SMACK: RECV (0):
    <body xmlns='http://jabber.org/protocol/httpbind'>
      <success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
        dj1saEFrUzVKMFRBMEJVbTg1djd5dE4xTUpZaE09
      </success>
    </body>
```

// ===== With only PR fixes: writer.flush(); readerConsumer = null; but withoug the following fixes ===== //
// Initialize the debugger before addBOSHClientResponseListener(new BOSHPacketReader());
// BOSHPacketReader may hold and send response prior to display of the request i.e. \<response/> before \<challenge/>

```
2023-12-11 12:33:54.915 6162-6310/org.atalk.android D/SMACK: SENT (0):
    <body ver='1.8' wait='60' xmpp:version='1.0' rid='6195788493952909' xmlns:xmpp='urn:xmpp:xbosh' hold='1' xml:lang='en' ack='1' to='atalk.sytes.net' xmlns='http://jabber.org/protocol/httpbind'>
    </body>
2023-12-11 12:33:55.198 6162-6314/org.atalk.android D/SMACK: RECV (0):
    <body xmpp:version='1.0' authid='1477509259581416251' xmlns='http://jabber.org/protocol/httpbind' sid='796ae552c9fea53ff10a1979429396d19745d430' wait='60' ver='1.11' polling='2' inactivity='30' hold='1' xmpp:restartlogic='true' requests='2' secure='true' maxpause='120' xmlns:xmpp='urn:xmpp:xbosh' xmlns:stream='http://etherx.jabber.org/streams' from='atalk.sytes.net'>
      <stream:features>
        <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
          <mechanism>
            PLAIN
          </mechanism>
          <mechanism>
            SCRAM-SHA-1
          </mechanism>
          <mechanism>
            X-OAUTH2
          </mechanism>
        </mechanisms>
        <register xmlns='http://jabber.org/features/iq-register'/>
      </stream:features>
    </body>
2023-12-11 12:33:55.301 6162-6310/org.atalk.android D/SMACK: SENT (0):
    <body rid='6195788493952910' sid='796ae552c9fea53ff10a1979429396d19745d430' xmlns='http://jabber.org/protocol/httpbind'>
      <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='SCRAM-SHA-1'>
        bixhPXN3YW5AYXRhbGsuc3l0ZXMubmV0LG49c3dhbixyPUJwMTZzKG9dd0xmb1lnN0haRkAjKko7PiReIXhbKiou
      </auth>
    </body>
2023-12-11 12:33:55.534 6162-6313/org.atalk.android D/SMACK: SENT (0):
    <body rid='6195788493952911' ack='6195788493952909' sid='796ae552c9fea53ff10a1979429396d19745d430' xmlns='http://jabber.org/protocol/httpbind'>
      <response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
        Yz1iaXhoUFhOM1lXNUFZWFJoYkdzdWMzbDBaWE11Ym1WMExBPT0scj1CcDE2cyhvXXdMZm9ZZzdIWkZAIypKOz4kXiF4WyoqLlV4eTcvUVBCQUNKbjg1TWdRZHhjQnc9PSxwPVZlT3pkVzExN0tMc3k4THZpQWJZWDlpcW84az0=
      </response>
    </body>
2023-12-11 12:33:55.538 6162-6314/org.atalk.android D/SMACK: RECV (0):
    <body xmlns='http://jabber.org/protocol/httpbind'>
      <challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
        cj1CcDE2cyhvXXdMZm9ZZzdIWkZAIypKOz4kXiF4WyoqLlV4eTcvUVBCQUNKbjg1TWdRZHhjQnc9PSxzPTdjNktCSnNaTHdTYjNZSytqdVRXb2c9PSxpPTQwOTY=
      </challenge>
    </body>
2023-12-11 12:33:55.558 6162-6310/org.atalk.android D/SMACK: SENT (0):
    <body xmpp:restart='true' rid='6195788493952912' xmlns:xmpp='urn:xmpp:xbosh' sid='796ae552c9fea53ff10a1979429396d19745d430' to='atalk.sytes.net' xmlns='http://jabber.org/protocol/httpbind'>
    </body>
2023-12-11 12:33:55.560 6162-6314/org.atalk.android D/SMACK: RECV (0):
    <body xmlns='http://jabber.org/protocol/httpbind'>
      <success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
        dj1mcFdSekE1SXltdTBrNys4K1hML3JncTVEd2s9
      </success>
    </body>
```

// ===== With the full PR fixes ===== //
```
2023-12-11 12:21:16.435 4703-5344/org.atalk.android D/SMACK: SENT (4):
    <body ver='1.8' wait='60' xmpp:version='1.0' rid='949729322134413' xmlns:xmpp='urn:xmpp:xbosh' hold='1' xml:lang='en' ack='1' to='atalk.sytes.net' xmlns='http://jabber.org/protocol/httpbind'>
    </body>
2023-12-11 12:21:16.637 4703-5348/org.atalk.android D/SMACK: RECV (4):
    <body xmpp:version='1.0' authid='1761920914298566866' xmlns='http://jabber.org/protocol/httpbind' sid='25ba67c4b943796418a2b7c064085327ab9c35ac' wait='60' ver='1.11' polling='2' inactivity='30' hold='1' xmpp:restartlogic='true' requests='2' secure='true' maxpause='120' xmlns:xmpp='urn:xmpp:xbosh' xmlns:stream='http://etherx.jabber.org/streams' from='atalk.sytes.net'>
      <stream:features>
        <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
          <mechanism>
            PLAIN
          </mechanism>
          <mechanism>
            SCRAM-SHA-1
          </mechanism>
          <mechanism>
            X-OAUTH2
          </mechanism>
        </mechanisms>
        <register xmlns='http://jabber.org/features/iq-register'/>
      </stream:features>
    </body>
2023-12-11 12:21:16.667 4703-5344/org.atalk.android D/SMACK: SENT (4):
    <body rid='949729322134414' sid='25ba67c4b943796418a2b7c064085327ab9c35ac' xmlns='http://jabber.org/protocol/httpbind'>
      <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='SCRAM-SHA-1'>
        bixhPXN3YW5AYXRhbGsuc3l0ZXMubmV0LG49c3dhbixyPTdiSVxeVnVMU0ZoWT8zVVlSa2psdkVMeks/e3BaQUwp
      </auth>
    </body>
2023-12-11 12:21:16.683 4703-5348/org.atalk.android D/SMACK: RECV (4):
    <body xmlns='http://jabber.org/protocol/httpbind'>
      <challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
        cj03YklcXlZ1TFNGaFk/M1VZUmtqbHZFTHpLP3twWkFMKUhqVjVlVFUvdzJFaW9yQjlGdHh3T3c9PSxzPTdjNktCSnNaTHdTYjNZSytqdVRXb2c9PSxpPTQwOTY=
      </challenge>
    </body>
2023-12-11 12:21:16.689 4703-5347/org.atalk.android D/SMACK: SENT (4):
    <body rid='949729322134415' ack='949729322134413' sid='25ba67c4b943796418a2b7c064085327ab9c35ac' xmlns='http://jabber.org/protocol/httpbind'>
      <response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
        Yz1iaXhoUFhOM1lXNUFZWFJoYkdzdWMzbDBaWE11Ym1WMExBPT0scj03YklcXlZ1TFNGaFk/M1VZUmtqbHZFTHpLP3twWkFMKUhqVjVlVFUvdzJFaW9yQjlGdHh3T3c9PSxwPXdNb2c5N3UzQktON1FHaFVQRzQ3MHVjZXdldz0=
      </response>
    </body>
2023-12-11 12:21:16.702 4703-5348/org.atalk.android D/SMACK: RECV (4):
    <body xmlns='http://jabber.org/protocol/httpbind'>
      <success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
        dj0yTzRqVzJXWHdEUDdvNjdJSkdNU3Rmc0NMTkk9
      </success>
    </body>
2023-12-11 12:21:16.704 4703-5344/org.atalk.android D/SMACK: SENT (4):
    <body xmpp:restart='true' rid='949729322134416' xmlns:xmpp='urn:xmpp:xbosh' sid='25ba67c4b943796418a2b7c064085327ab9c35ac' to='atalk.sytes.net' xmlns='http://jabber.org/protocol/httpbind'>
    </body>
```

Link: https://github.com/igniterealtime/Smack/pull/554
2023-12-11 11:16:45 +01:00
441d677644
Initial support for XEP-0446: File Metadata Element
Also adds initial support for XEP-0264: Jingle Content Thumbnails

Solves SMACK-894
2023-12-08 14:46:51 +01:00
Florian Schmaus
90b8eee0d1 [extensions] Drop newlines in test string within GroupChatInvitationElementTest 2023-12-07 15:18:04 +01:00
664a141190 [extensions] Improved Support for Direct MUC Invitations (XEP-0249)
[flow: rebase of paul's initial submission which required adjustments]

Co-authored-by: Florian Schmaus <flo@geekplace.eu>
2023-12-07 15:01:44 +01:00
Florian Schmaus
726dbc0d27 [core] Add XmlStringBuilder.jidAttribute(Jid) and optJidAttribute(Jid) 2023-12-07 15:01:43 +01:00
Florian Schmaus
b7218e3a72 Smack 4.5.0-alpha3-SNAPSHOT 2023-12-07 11:57:43 +01:00
Florian Schmaus
39fe3fc5bb Smack 4.5.0-alpha2 2023-12-07 11:42:18 +01:00
Florian Schmaus
610e5dd803 [omemo-signal-integration-test] Add Bouncy Castle as security provider 2023-12-07 11:40:20 +01:00
Florian Schmaus
9e5564a597 [omemo] Do not swallow the exception in OmemoAesCipher 2023-12-07 11:38:25 +01:00
Florian Schmaus
7135977cb7 [sinttest] Make AbstractMultiUserChatIntegrationTest abstract 2023-12-07 11:26:18 +01:00
Florian Schmaus
f74f47f6d4 Merge branch '4.4' 2023-12-07 11:22:43 +01:00
Florian Schmaus
390f6f0fa7 [core] Fix busy-loop in SmackReactor
Fixes SMACK-938.
2023-12-07 11:22:38 +01:00
Florian Schmaus
1e666197a3 [sinttest] Display Java version on startup 2023-12-07 11:20:37 +01:00
Florian Schmaus
9acee05e5e [core] Improve how the selected keys are copied in SmackReactor 2023-12-07 11:20:37 +01:00
Florian Schmaus
844ebbf4c5 [core] Add milliseconds to ConsoleDebugger's timestamp 2023-12-06 20:55:37 +01:00
Florian Schmaus
688c06020b [sinttest] Improve message ouf XmppConnectionStressTest 2023-12-06 20:55:02 +01:00
Florian Schmaus
7fcc8a9bd3 [sinttest] Set default timeout to 47 seconds
Using 60 seconds makes it sometimes easy to miss that the some action
was 1 minute after the timeout, because only a single digit in the
timestamp changes. Using a prime number as timeout makes this more
obvious.
2023-12-06 20:53:23 +01:00
Florian Schmaus
2337a446a5 Re-work ad-hoc command (XEP-0050) implementation
Fixes SMACK-933.
2023-12-06 12:40:53 +01:00
Florian Schmaus
dac06b04c3 [core] Add XmlStringBuilder.setAppendApproach() 2023-11-28 11:04:24 +01:00
Florian Schmaus
04dc212db8 Add smack-examples 2023-11-28 10:46:16 +01:00
Florian Schmaus
5a78534443 [core] Mark LazyStringBuilder's String cache as transient 2023-11-26 21:35:19 +01:00
Florian Schmaus
b35b67c360 [repl] Bump Scala to 2.13.12, Ammonite to 2.5.11, and Scalastyle plugin to 2.1.0 2023-11-26 21:34:14 +01:00
Florian Schmaus
6322f4f826 [core] Add global option to flatten when appending in XmlStringBuilder
For certain use cases, this provides a performance improvement,
probably due better cache locality. However, it comes with the cost of
additional memory consumption.

This was initially suggested by Boris Grozev, who also reported a
significant performance problem of
XmlStringBuilder/LazyStringBuilder. However, the main cause of the
performance probelm was the missing caching of LazyStringBuilder. The
length of the lazy string is now cached by LazyStringBuidler since
70e48300a6 ("[core] Cache length in LazyStringBuilder"), which
accounts for large performance improvement. A significantly smaller
improvement is achieved by this commit and setting
XmlStringBuilder.FLAT_APPEND to 'true'.

Suggested-by: Boris Grozev <boris@jitsi.org>
2023-11-26 21:34:13 +01:00
Florian Schmaus
70e48300a6 [core] Cache length in LazyStringBuilder 2023-11-26 21:24:17 +01:00
Florian Schmaus
9203907e66
Merge pull request #567 from guusdk/sint_trim-config
[sinttest] Trim externally-provided configuration
2023-11-26 17:12:39 +00:00
Florian Schmaus
38dd64835f Merge branch '4.4' 2023-11-26 17:53:07 +01:00
Florian Schmaus
0fb8bfdf6c [CHANGELOG] fix markdown listing 2023-11-26 17:52:32 +01:00
Florian Schmaus
472bee8497 [sinttest] drop empty line 2023-11-26 13:58:09 +01:00
Florian Schmaus
535ecd67ee
Merge pull request #573 from Flowdalic/sinttest-ibr
[sinttest] Fix IBR-based account registration
2023-11-26 12:56:13 +00:00
Florian Schmaus
915626123d [sinttest] Fix IBR-based account registration
When performing IBR-based account registration, we do not need to
login nor are the admin credentials typically available.

Suggested-by: Guus der Kinderen <guus@goodbytes.nl>
2023-11-26 13:55:35 +01:00
Guus der Kinderen
9055878748 [sinttest] Fix typos in log and exception messages 2023-11-25 20:08:51 +01:00
Florian Schmaus
6859de95d0
Merge pull request #564 from vanitasvitae/bumpLibSignal
Bump libsignal-protocol-java to 2.8.1
2023-11-25 19:00:45 +00:00
Florian Schmaus
0469185b62
Merge pull request #517 from Neustradamus/slf4j
Add SLF4J 2.0+
2023-11-25 19:00:20 +00:00
Florian Schmaus
2dc12db6f4
Merge pull request #563 from vanitasvitae/bumpPgpainless
Bump pgpainless
2023-11-25 19:00:02 +00:00
Florian Schmaus
7eabdaf8f7
Merge pull request #570 from guusdk/SMACK-935_Websocket-open-element
Improve handling of expanded Websocket 'open' element
2023-11-25 18:59:40 +00:00
Florian Schmaus
097ab20485 [websocket] Do not swallow exceptions and use QName
Follow up on c4d11eae299e ("[websocket] Reduce fragility")
2023-11-25 19:59:05 +01:00
Florian Schmaus
2ebffa7615 Merge remote-tracking branch 'origin/pr/571' 2023-11-25 19:58:54 +01:00
Florian Schmaus
0552440c1a Merge branch '4.4' 2023-11-25 19:44:29 +01:00
Florian Schmaus
84ec2c8c2f Smack 4.4.8-SNAPSHOT 2023-11-25 19:30:49 +01:00
Florian Schmaus
6d99ba7ffb Smack 4.4.7 2023-11-25 19:07:40 +01:00
Florian Schmaus
b5b4418406 Merge branch '4.4' 2023-11-25 17:36:15 +01:00
Florian Schmaus
2e8f83c579
Merge pull request #572 from Flowdalic/sync-entity-caps
[caps] Use a synchronous listener for incoming presence stanzas
2023-11-25 13:26:12 +01:00
Florian Schmaus
5560fb4752 [chatmarkers] Deprecate ChatMarkers.isSupportedByServer()
Fixes SMACK-934.
2023-11-25 11:24:37 +01:00
Florian Schmaus
a270542397 [core] Improve javadoc for listeners
With 92f253cc74 ("[core] Replace
AbstractXMPPConnection.inOrderListeners") we changes the behavior of
listeners. This commit documents the expectations to the user.
2023-11-24 12:59:04 +01:00
Florian Schmaus
f593b6d0a0 [core] Whitespace fix in XMPPConnection's javadoc 2023-11-24 12:18:19 +01:00
Florian Schmaus
ccfbf9f346 [caps] Use a synchronous listener for incoming presence stanzas
Fixes SMACK-937.
2023-11-24 12:15:32 +01:00
Guus der Kinderen
8c1fa1cc91 [websocket] Reduce fragility
Replace string-based comparison with a XML parsing when checking for 'open' and 'close' elements.
2023-11-13 16:03:41 +01:00
Guus der Kinderen
6244a213c8 [websocket] Improve handling of expanded 'open' element
Prior to this fix, Smack requires the 'open' element send on a websocket connection to be collapsed. With the change in
this commit, an expanded (eg: `<open ...></open>`) element can also be used.

fixes SMACK-935
2023-10-27 13:33:04 +02:00
Florian Schmaus
c7f3e231d0
Merge pull request #568 from guusdk/intellij-icon
Add icon to IntelliJ metadata
2023-10-26 19:08:35 +00:00
Guus der Kinderen
e2d136d992 Add icon to IntelliJ metadata 2023-10-05 10:31:41 +02:00
Guus der Kinderen
92d4cf5c77 [sinttest] Trim externally-provided configuration
Smack integration test configuration is provided externally. Guard against accidental whitespace inclusion by trimming values.
2023-09-29 20:37:03 +02:00
38844ee340
Bump libsignal-protocol-java to 2.8.1 2023-06-24 11:28:53 +02:00
430795bb9e
Bump PGPainless to 1.5.3 2023-06-24 11:10:24 +02:00
9bfaf674b1
Bump BC to 1.73 2023-06-24 11:10:10 +02:00
Neustradamus
3b8ebb24c7 Add SLF4J 2.0+
http://www.slf4j.org/news.html
2022-03-04 05:43:15 +01:00
198c51356d Add initial support for XEP-0103 and XEP-0104: URL Address Information 2020-12-31 00:10:18 +01:00
518 changed files with 10570 additions and 5589 deletions

View file

@ -6,13 +6,14 @@ jobs:
build:
name: Build Smack
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
strategy:
matrix:
java:
- 11
- 17
- 21
env:
PRIMARY_JAVA_VERSION: 11
PRIMARY_JAVA_VERSION: 21
steps:
- name: Checkout
@ -52,10 +53,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-23"
# Testing
- name: Gradle Check
@ -71,15 +72,22 @@ jobs:
run: ./gradlew javadocAll --stacktrace
# Test Coverage Report
- name: Jacoco Test Coverage
- name: Aggregated Jacoco Test Coverage Report
if: ${{ matrix.java == env.PRIMARY_JAVA_VERSION }}
run: ./gradlew jacocoRootReport coveralls
env:
COVERALLS_REPO_TOKEN: S2ecSJja2cKJa9yv45C8ZFPohXuRrTXKd
run: |
./gradlew smack-java11-full:testCodeCoverageReport
# 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
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: smack-java-${{ matrix.java }}
path: |

2
.gitignore vendored
View file

@ -3,6 +3,7 @@
*.iml
*.ipr
*.iws
!.idea/icon.svg
# Mac OS X
.DS_Store
@ -11,7 +12,6 @@
.project
.settings
.gradle
gradle.properties
build/
core/build/

89
.idea/icon.svg Normal file
View file

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 399.2693 389.25732"
height="389.25732"
width="399.26932"
xml:space="preserve"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="smack-logo-plain.svg"><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="834"
inkscape:window-height="1044"
id="namedview3432"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="0.65684805"
inkscape:cx="238.37045"
inkscape:cy="159.12321"
inkscape:window-x="2520"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg2" /><metadata
id="metadata8"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs6"><clipPath
id="clipPath18"
clipPathUnits="userSpaceOnUse"><path
id="path16"
d="M 0,600 800,600 800,0 0,0 Z"
inkscape:connector-curvature="0" /></clipPath><clipPath
id="clipPath30"
clipPathUnits="userSpaceOnUse"><path
id="path28"
d="m 351.001,359.31 c -17.234,-7.3 -51.945,15.909 -51.945,15.909 l 0,0 c 0,0 31.115,-33.702 27.068,-47.102 l 0,0 c -4.048,-13.401 -44.827,-30.694 -44.827,-30.694 l 0,0 c 0,0 51.173,5.823 53.705,-8.205 l 0,0 c 2.528,-14.031 -3.951,-54.186 -3.951,-54.186 l 0,0 c 0,0 25.887,37.471 39.897,36.872 l 0,0 c 14.012,-0.597 39.902,-36.872 39.902,-36.872 l 0,0 c 0,0 -14.178,43.955 -3.952,54.186 l 0,0 c 10.225,10.229 53.706,8.205 53.706,8.205 l 0,0 c 0,0 -43.02,12.932 -44.827,30.694 l 0,0 c -1.81,17.759 27.07,47.102 27.07,47.102 l 0,0 c 0,0 -35.718,-23.04 -51.948,-15.909 l 0,0 c -16.232,7.13 -19.951,50.533 -19.951,50.533 l 0,0 c 0,0 -2.718,-43.232 -19.947,-50.533"
inkscape:connector-curvature="0" /></clipPath><radialGradient
id="radialGradient40"
spreadMethod="pad"
gradientTransform="matrix(89.254456,0,0,-89.254456,370.9502,322.4375)"
gradientUnits="userSpaceOnUse"
r="1"
cy="0"
cx="0"
fy="0"
fx="0"><stop
id="stop36"
offset="0"
style="stop-opacity:1;stop-color:#fdbe10" /><stop
id="stop38"
offset="1"
style="stop-opacity:1;stop-color:#f16422" /></radialGradient></defs><g
transform="matrix(1.3333333,0,0,-1.3333333,-294.96293,630.13412)"
id="g10"><g
id="g12"><g
clip-path="url(#clipPath18)"
id="g14"><g
transform="translate(370.9482,472.6006)"
id="g20"><path
id="path22"
style="fill:#fdbe10;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 0,0 6.213,-72.485 33.318,-84.392 27.104,-11.905 86.753,26.569 86.753,26.569 0,0 -48.228,-49.006 -45.209,-78.665 3.022,-29.661 74.864,-51.262 74.864,-51.262 0,0 -72.61,3.382 -89.688,-13.703 -17.078,-17.084 6.597,-90.49 6.597,-90.49 0,0 -43.237,60.579 -66.635,61.578 -23.4,1.003 -66.633,-61.578 -66.633,-61.578 0,0 10.826,67.062 6.601,90.49 -4.229,23.431 -89.694,13.703 -89.694,13.703 0,0 68.108,28.882 74.865,51.262 6.757,22.378 -45.21,78.665 -45.21,78.665 0,0 57.978,-38.76 86.757,-26.569 C -4.54,-72.2 0,0 0,0"
inkscape:connector-curvature="0" /></g></g></g><g
id="g24"><g
clip-path="url(#clipPath30)"
id="g26"><g
id="g32"><g
id="g34"><path
id="path42"
style="fill:url(#radialGradient40);stroke:none"
d="m 351.001,359.31 c -17.234,-7.3 -51.945,15.909 -51.945,15.909 l 0,0 c 0,0 31.115,-33.702 27.068,-47.102 l 0,0 c -4.048,-13.401 -44.827,-30.694 -44.827,-30.694 l 0,0 c 0,0 51.173,5.823 53.705,-8.205 l 0,0 c 2.528,-14.031 -3.951,-54.186 -3.951,-54.186 l 0,0 c 0,0 25.887,37.471 39.897,36.872 l 0,0 c 14.012,-0.597 39.902,-36.872 39.902,-36.872 l 0,0 c 0,0 -14.178,43.955 -3.952,54.186 l 0,0 c 10.225,10.229 53.706,8.205 53.706,8.205 l 0,0 c 0,0 -43.02,12.932 -44.827,30.694 l 0,0 c -1.81,17.759 27.07,47.102 27.07,47.102 l 0,0 c 0,0 -35.718,-23.04 -51.948,-15.909 l 0,0 c -16.232,7.13 -19.951,50.533 -19.951,50.533 l 0,0 c 0,0 -2.718,-43.232 -19.947,-50.533"
inkscape:connector-curvature="0" /></g></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 4.9 KiB

View file

@ -1,5 +1,31 @@
# 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
- [SMACK-929](https://igniterealtime.atlassian.net/browse/SMACK-929) Ignore IPv6 Zone IDs in incoming Jingle candidates
- [SMACK-934](https://igniterealtime.atlassian.net/browse/SMACK-934) Deprecate and remove ChatMarkersManager.isSupportedByServer\(\)
- [SMACK-937](https://igniterealtime.atlassian.net/browse/SMACK-937) Avoid unnecessary feature lookups by making the EntityCaps listener synchronous
### Bug
- [SMACK-927](https://igniterealtime.atlassian.net/browse/SMACK-927) Deadlock due to recveive listeners may be invoked after AbstractXMPPConnection.invokeStanzaCollectorsAndNotifyRecvListeners\(\) returned
- [SMACK-930](https://igniterealtime.atlassian.net/browse/SMACK-930) Rename ELEMENT 'candidate-activated' to 'activated' per XEP-0260
- [SMACK-931](https://igniterealtime.atlassian.net/browse/SMACK-931) IQ error stanza generation does not allow adding of an extension element
# 4.4.6 -- 2022-06-29
### Bug

30
Makefile Normal file
View file

@ -0,0 +1,30 @@
GRADLE ?= ./gradlew
.PHONY: all
all: check jacocoRootReport javadocAll sinttest
.PHONY: codecov
codecov:
$(GRADLE) smack-java11-full:testCodeCoverageReport
echo "Report available at smack-java11-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"

14
build-logic/build.gradle Normal file
View file

@ -0,0 +1,14 @@
plugins {
id 'groovy-gradle-plugin'
}
repositories {
gradlePluginPortal()
}
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 "ru.vyarus:gradle-animalsniffer-plugin:1.7.1"
}

View file

@ -0,0 +1 @@
rootProject.name = 'smack-build-logic'

View file

@ -0,0 +1,6 @@
compileJava {
options.bootstrapClasspath = files(androidBootClasspath)
}
javadoc {
classpath += files(androidBootClasspath)
}

View file

@ -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}:6.0_r3@signature"
}
animalsniffer {
sourceSets = [sourceSets.main]
}

View file

@ -0,0 +1,12 @@
plugins {
id 'application'
}
application {
applicationDefaultJvmArgs = ["-enableassertions"]
}
run {
// Pass all system properties down to the "application" run
systemProperties System.getProperties()
}

View file

@ -0,0 +1,37 @@
ext {
javaVersion = JavaVersion.VERSION_11
javaMajor = javaVersion.getMajorVersion()
smackMinAndroidSdk = 23
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
}

View file

@ -0,0 +1,367 @@
plugins {
id 'biz.aQute.bnd.builder'
id 'checkstyle'
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.32.0'
}
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
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()
}

View file

@ -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"
}

View file

@ -1,347 +1,20 @@
buildscript {
repositories {
jcenter()
maven { url 'https://plugins.gradle.org/m2/' }
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"
}
}
plugins {
id 'ru.vyarus.animalsniffer' version '1.5.0'
id 'net.ltgt.errorprone' version '1.3.0'
// Use e.g. "gradle <task> taskTree" to show its dependency tree.
id 'com.dorongold.task-tree' version '1.5'
id 'com.github.kt3k.coveralls' version '2.10.2'
// 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-integration-test',
':smack-omemo-signal-integration-test',
':smack-repl',
':smack-websocket-java11',
].collect { project(it) }
java11Projects += getRootProject()
java8Projects = allprojects - java11Projects
}
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-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.0.0, 1.0.999]'
miniDnsVersion = '[1.0.0, 1.0.999]'
smackMinAndroidSdk = 19
junitVersion = '5.7.1'
commonsIoVersion = '2.6'
bouncyCastleVersion = '1.71'
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/traget 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 paramater 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"
// 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 resovled
// 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 ->
@ -390,315 +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 resovled, 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: 'org.kordamp.gradle.clirr'
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
}
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')
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}:4.4.2_r4@signature"
}
animalsniffer {
sourceSets = [sourceSets.main]
}
}
// 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
}
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 }
}
// 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
@ -706,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 {
@ -717,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
@ -791,7 +91,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
}

View file

@ -0,0 +1,20 @@
/**
*
* Copyright 20XX John Doe
*
* 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
*/

5
gradle.properties Normal file
View file

@ -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

Binary file not shown.

View file

@ -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

297
gradlew vendored
View file

@ -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" "$@"

33
gradlew.bat vendored
View file

@ -13,6 +13,8 @@
@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
@rem ##########################################################################
@ -26,6 +28,7 @@ if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
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

11
repl
View file

@ -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

View file

@ -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."

View file

@ -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]*//" | \

View file

@ -1,221 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Smack Readme</title>
<style type="text/css">
/* global font and body settings */
body {
font-size : 100%;
background-color : #d3d6d9;
padding: 0;
margin: 0 0 30px 0;
}
body, td, th {
font-family : arial, helvetica, sans-serif;
font-size : 10pt;
}
pre, tt, code {
font-family : courier new, monospace;
font-size : 9pt;
}
#pageContainer {
display: block;
position: relative;
clear: both;
background-color: #fff;
border: 1px solid #999;
padding: 40px;
margin: 30px;
-moz-border-radius: 6px;
}
#pageHeader {
display: block;
position: relative;
height: 80px;
background-color: #e7eaee;
border: 1px solid #cccccc;
border-bottom: none;
-moz-border-radius: 5px 5px 0 0;
margin: 10px 0 0 0;
}
#pageBody {
margin: 0 18px 0 20px;
}
/* anchors */
a:link {
color: #11568c;
}
a:visited {
color: #571c8d;
}
a:hover {
color: #7a1d42;
text-decoration : underline;
}
a:active {
color: #7a1d42;
}
/* page header elements (logo and navigation) */
.navigation {
display: block;
position: relative;
height: 20px;
background-color: #335588;
border: 1px solid #cccccc;
border-top: none;
color: #ffffff;
font-size: 11px;
line-height: 18px;
padding: 0 0 0 0;
margin: 0 0 25px 0;
overflow: hidden;
}
.navigation a {
margin: 0 20px 0 20px;
}
.navigation a:link { color: #ffffff; }
.navigation a:visited { color: #ffffff; }
.navigation a:hover { color: #ffffff; }
.navigation a:active { color: #ffffff; }
/* headings */
h1 {
display: block;
position: relative;
font-size : 1.7em;
font-weight : bold;
color: #670e15;
padding: 0;
margin: 30px 0 0 20px;
}
h2 {
font-size : 1.3em;
font-weight : bold;
margin: 40px 0 6px 0;
padding: 0;
color: #335588;
}
h3 {
font-size : 1.0em;
font-weight : bold;
margin: 25px 0 3px 0;
padding: 0;
color: #334466;
}
/* general elements */
p {
margin: 0 0 15px 0;
}
ul {
margin: 5px 0 15px 15px;
}
li {
padding-bottom : 4px;
}
tt {
font-family : courier new, monospace;
font-weight : bold;
color : #060;
}
hr {
display: block;
height: 1px;
background-color: #999999;
border: none;
margin: 40px 0 20px 0;
}
</style>
</head>
<body>
<div id="pageContainer">
<div id="pageHeader">
<h1>Smack Readme</h1>
</div>
<div class="navigation">
<a href="README.html">Readme</a>|<a href="changelog.html"><strong>Changelog</strong></a>
</div>
<div id="pageBody">
<p>
<table border=0>
<tr>
<td align="right">version:</td>
<td><b>@version@</b></td>
</tr>
<tr>
<td align="right">released:</td>
<td><b>@releasedate@</b></td>
</tr>
</table>
<p>
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.
</p>
<p>
<b>This is not the real README.</b> Please visit
<center>
<a href="https://www.igniterealtime.org/projects/smack/readme">https://www.igniterealtime.org/projects/smack/readme</a>
</center>
for the README of the current stable Smack version.
</p>
<p>
Smack tries to depend on as few as possible libraries. The only
requirement is <a href="http://jxmpp.org">jXMPP</a>. For DNS
resolution we recommend to
use <a href="http://minidns.org">MiniDNS</a>.
</p>
<p>
Start off by viewing the <a href="documentation/index.html">documentation</a>
that can be found in the "documentation" directory included with this distribution.
</p>
Further information can be found on the <a href="http://www.igniterealtime.org/projects/smack">
Smack website</a>. If you need help using or would like to make contributions or
fixes to the code, please visit the
<a href="https://community.igniterealtime.org">online forum</a>.
</p>
<p><b>Changelog and Upgrading</b><p>
View the <a href="changelog.html">changelog</a> for a list of changes since the
last release.
<p><b>License Agreements</b><p>
<ul>
<li>Use of the Smack source code is governed by the Apache License Version 2.0:
<pre>
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.
</pre></li>
<li>Smack contains icons and images licensed from INCORS GmbH. You are not licensed
to use these icons outside of Smack.</li>
<li>Third-party source code is licensed as noted in their source files.
</ul>
</div>
</div>
</body>
</html>

View file

@ -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
@ -6,6 +10,7 @@ rootProject.name = 'Smack'
include 'smack-core',
'smack-im',
'smack-tcp',
'smack-examples',
'smack-extensions',
'smack-experimental',
'smack-debug',
@ -22,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',

View file

@ -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)
}

View file

@ -1 +1 @@
../../../../../../../smack-java8-full/src/main/java/org/jivesoftware/smackx/package-info.java
../../../../../../../smack-java11-full/src/main/java/org/jivesoftware/smackx/package-info.java

View file

@ -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.
@ -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;
/**
@ -121,6 +122,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<Map.Entry<XMPPConnection, ServerPingWithAlarmManager>> managers;
@ -163,7 +165,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.
*
@ -173,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);

View file

@ -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)
}

View file

@ -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<Exception> initialize() {
SmackConfiguration.setDefaultHostnameVerifier(new StrictHostnameVerifier());
Base64.setEncoder(AndroidBase64Encoder.INSTANCE);

View file

@ -28,7 +28,7 @@ import android.util.Log;
* implementation, therefore {@link org.jivesoftware.smack.debugger.JulDebugger} is preferred.
* </p>
* 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 <code>printInterpreted</code> static variable to <code>true</code>.
*
*/

View file

@ -1 +1 @@
../../../../../../../smack-java8-full/src/main/java/org/jivesoftware/smackx/package-info.java
../../../../../../../smack-java11-full/src/main/java/org/jivesoftware/smackx/package-info.java

View file

@ -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."""

View file

@ -172,14 +172,15 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
client = BOSHClient.create(cfgBuilder.build());
client.addBOSHClientConnListener(new BOSHConnectionListener());
client.addBOSHClientResponseListener(new BOSHPacketReader());
// Initialize the debugger
// Initialize the debugger before addBOSHClientResponseListener(new BOSHPacketReader());
// BOSHPacketReader may hold and send response prior to display of the request i.e. <response/> before <challenge/>
if (debugger != null) {
initDebugger();
}
client.addBOSHClientConnListener(new BOSHConnectionListener());
client.addBOSHClientResponseListener(new BOSHPacketReader());
// Send the session creation request
client.send(ComposableBody.builder()
.setNamespaceDefinition("xmpp", XMPP_BOSH_NS)
@ -359,10 +360,11 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
CloseableUtil.maybeClose(reader, LOGGER);
CloseableUtil.maybeClose(writer, LOGGER);
// set readerConsumer = null before reader to avoid NPE reference
readerConsumer = null;
readerPipe = null;
reader = null;
writer = null;
readerConsumer = null;
}
/**
@ -440,6 +442,8 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
if (event.getBody() != null) {
try {
writer.write(event.getBody().toXML());
// Fix all BOSH sent debug messages not shown
writer.flush();
} catch (Exception e) {
// Ignore
}

View file

@ -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')
@ -28,7 +31,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'.
@ -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 {

View file

@ -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);
}
/**

View file

@ -487,7 +487,7 @@ public abstract class SmackTestCase extends TestCase {
}
/**
* Returns the name of the configuration file related to <b>this</b> test case. By default all
* Returns the name of the configuration file related to <b>this</b> 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 <test case class name>.xml
* (e.g. RosterTest.xml).

View file

@ -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
}
}

View file

@ -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;
@ -128,7 +129,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).
* <p>
@ -387,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;
@ -1067,6 +1069,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
}
@Override
@SuppressWarnings("TypeParameterUnusedInFormals")
public <I extends IQ> I sendIqRequestAndWaitForResponse(IQ request)
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
StanzaCollector collector = createStanzaCollectorAndSend(request);
@ -1214,7 +1217,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
}
Stanza packet = (Stanza) sendTopLevelStreamElement;
final List<StanzaListener> listenersToNotify = new LinkedList<>();
final List<StanzaListener> listenersToNotify = new ArrayList<>();
synchronized (sendListeners) {
for (ListenerWrapper listenerWrapper : sendListeners.values()) {
if (listenerWrapper.filterMatches(packet)) {
@ -1242,27 +1245,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 <MPB extends MessageOrPresenceBuilder<MP, MPB>, MP extends MessageOrPresence<MPB>> void addInterceptor(
Map<Consumer<MPB>, GenericInterceptorWrapper<MPB, MP>> interceptors, Consumer<MPB> interceptor,
Predicate<MP> filter) {
@ -1305,7 +1287,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
private static <MPB extends MessageOrPresenceBuilder<MP, MPB>, MP extends MessageOrPresence<MPB>> MP fireMessageOrPresenceInterceptors(
MP messageOrPresence, Map<Consumer<MPB>, GenericInterceptorWrapper<MPB, MP>> interceptors) {
List<Consumer<MPB>> interceptorsToInvoke = new LinkedList<>();
List<Consumer<MPB>> interceptorsToInvoke = new ArrayList<>();
synchronized (interceptors) {
for (GenericInterceptorWrapper<MPB, MP> interceptorWrapper : interceptors.values()) {
if (interceptorWrapper.filterMatches(messageOrPresence)) {
@ -1340,7 +1322,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
* @return the, potentially modified stanza, after the interceptors are run.
*/
private Stanza firePacketInterceptors(Stanza packet) {
List<StanzaListener> interceptorsToInvoke = new LinkedList<>();
List<StanzaListener> interceptorsToInvoke = new ArrayList<>();
synchronized (interceptors) {
for (InterceptorWrapper interceptorWrapper : interceptors.values()) {
if (interceptorWrapper.filterMatches(packet)) {
@ -1625,7 +1607,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<StanzaListener> listenersToNotify = new LinkedList<>();
final Collection<StanzaListener> listenersToNotify = new ArrayList<>();
extractMatchingListeners(packet, asyncRecvListeners, listenersToNotify);
for (final StanzaListener listener : listenersToNotify) {
asyncGoLimited(new Runnable() {
@ -1951,7 +1933,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
// Default implementation does nothing
}
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"})
@Override
public <F extends XmlElement> F getFeature(QName qname) {
return (F) streamFeatures.get(qname);
@ -2196,6 +2178,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<Runnable> deferredAsyncRunnables = new LinkedList<>();
private int deferredAsyncRunnablesCount;

View file

@ -53,14 +53,14 @@ import java.util.concurrent.Executor;
public class AsyncButOrdered<K> {
/**
* 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<K, Queue<Runnable>> 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<K, Handler> threadActiveMap = new HashMap<>();

View file

@ -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.
@ -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)}.
* <p>
* 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);
@ -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 <code>null</code>.
*/
public Locale getLanguage() {
return language;
@ -544,19 +544,21 @@ public abstract class ConnectionConfiguration {
* Returns the xml:lang string of the stream language to use when connecting to the server.
*
* <p>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.</p>
* the removal of the xml:lang tag from the stream.</p>
*
* @return the stream language to use when connecting to the server.
* @return the stream language to use when connecting to the server or <code>null</code>.
*/
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;
}
/**
@ -583,7 +585,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 +594,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 +609,7 @@ public abstract class ConnectionConfiguration {
/**
* Return the explicitly enabled SASL mechanisms. May return <code>null</code> 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 <code>null</code>.
*/
@ -670,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();
@ -857,22 +860,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 +1008,6 @@ public abstract class ConnectionConfiguration {
return getThis();
}
/**
* Sets a custom SSLContext for creating SSL sockets.
* <p>
* For more information on how to create a SSLContext see <a href=
* "http://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#X509TrustManager"
* >Java Secure Socket Extension (JSEE) Reference Guide: Creating Your Own X509TrustManager</a>
*
* @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.
* <p>
@ -1090,8 +1058,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 <code>false</code> value.
*
@ -1187,7 +1154,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();
@ -1266,7 +1235,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 +1293,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 {

View file

@ -53,7 +53,7 @@ import org.jxmpp.jid.EntityBareJid;
*
* <p>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..</p>
* server supports SASL then Smack will try to authenticate using SASL.</p>
*
* <p>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

View file

@ -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;

View file

@ -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.
*/

View file

@ -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.

View file

@ -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.
* <p>
* So far this means that:

View file

@ -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.
@ -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);
@ -276,8 +277,7 @@ public class SmackReactor {
setInterestOpsCancelledKeySafe(selectionKey, 0);
}
selectedKeys = new ArrayList<>(selectedKeySet.size());
selectedKeys.addAll(selectedKeySet);
selectedKeys = new ArrayList<>(selectedKeySet);
selectedKeySet.clear();
}
@ -327,6 +327,12 @@ public class SmackReactor {
int currentReactorThreadCount = reactorThreads.size();
int myKeyCount = pendingSelectionKeysSize / currentReactorThreadCount;
// The division could result in myKeyCount being zero, even though there are pending selection keys.
// Therefore, ensure that this thread tries to get at least one pending selection key by invoking poll().
// Otherwise, it could happen that we end up in a busy loop, where myKeyCount is zero and this thread invokes
// selector.wakeup() below because pendingSelectionsKeys is not empty, but the woken up reactor thread wil
// end up with myKeyCount being zero again, restarting the busy-loop cycle.
if (myKeyCount == 0) myKeyCount = 1;
Collection<SelectionKey> selectedKeys = new ArrayList<>(myKeyCount);
for (int i = 0; i < myKeyCount; i++) {
SelectionKey selectionKey = pendingSelectionKeys.poll();

View file

@ -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 <code>null</code> if there are no more
* results.
*/
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"})
public synchronized <P extends Stanza> 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 extends Stanza> 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 extends Stanza> 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 extends Stanza> P nextResult() throws InterruptedException {
return nextResult(connection.getReplyTimeout());
}
@ -191,7 +193,7 @@ public final class StanzaCollector implements AutoCloseable {
* @return the next available stanza or <code>null</code> on timeout or connection error.
* @throws InterruptedException if the calling thread was interrupted.
*/
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"})
public <P extends Stanza> 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 extends Stanza> 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 extends Stanza> P nextResultOrThrow(long timeout) throws NoResponseException,
XMPPErrorException, InterruptedException, NotConnectedException {
P result;

View file

@ -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.
* <p>
* 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)}
* </p>
*
* @see XMPPConnection#addAsyncStanzaListener(StanzaListener, org.jivesoftware.smack.filter.StanzaFilter)
* @author Matt Tucker

View file

@ -91,23 +91,24 @@ import org.jxmpp.jid.EntityFullJid;
* <h2>Incoming Stanza Listeners</h2>
* Most callbacks (listeners, handlers, ) than you can add to a connection come in three different variants:
* <ul>
* <li>standard</li>
* <li>async (asynchronous)</li>
* <li>sync (synchronous)</li>
* <li>asynchronous - e.g., {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}</li>
* <li>synchronous - e.g., {@link #addSyncStanzaListener(StanzaListener, StanzaFilter)}</li>
* <li>other - e.g., {@link #addStanzaListener(StanzaListener, StanzaFilter)}</li>
* </ul>
* <p>
* Standard callbacks are invoked concurrently, but it is ensured that the same callback is never run concurrently.
* The callback's identity is used as key for that. The events delivered to the callback preserve the order of the
* causing events of the connection.
* </p>
* <p>
* 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.
* </p>
* <p>
* Synchronous callbacks are run synchronous to the main event loop of a connection. Hence they are invoked in the
* exact order of how events happen there, most importantly the arrival order of incoming stanzas. You should only
* use synchronous callbacks in rare situations.
* Synchronous callbacks are invoked concurrently, but it is ensured that the same callback is never run concurrently
* and that they are executed in order. That is, if both stanza A and B trigger the same callback, and A arrives before
* B, then the callback will be invoked with A first, and then B. Furthermore, those callbacks are not executed within
* the main loop. However it is still advisable that those callbacks do not block or only block briefly.
* </p>
* <p>
* Other callbacks are run synchronous to the main event loop of a connection and are executed within the main loop.
* <b>This means that if such a callback blocks, the main event loop also blocks, which can easily cause deadlocks.
* Therefore, you should avoid using those callbacks unless you know what you are doing.</b>
* </p>
* <h2>Stanza Filters</h2>
* Stanza filters allow you to define the predicates for which listeners or collectors should be invoked. For more
@ -241,7 +242,7 @@ public interface XMPPConnection {
* </p>
*
* @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.
@ -264,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
@ -317,6 +318,7 @@ public interface XMPPConnection {
* @throws InterruptedException if the calling thread was interrupted.
* @since 4.3
*/
@SuppressWarnings("TypeParameterUnusedInFormals")
<I extends IQ> I sendIqRequestAndWaitForResponse(IQ request)
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException;
@ -422,7 +424,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);
@ -448,7 +449,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);
@ -482,34 +482,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.
*
* <p>
* NOTE: For a similar functionality on incoming stanzas, see {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}.
* </p>
*
* @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
@ -610,23 +582,6 @@ public interface XMPPConnection {
*/
FromMode getFromMode();
/**
* Get the feature stanza extensions for a given stream feature of the
* server, or <code>null</code> if the server doesn't support that feature.
*
* @param <F> {@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 <code>null</code>
* @deprecated use {@link #getFeature(Class)} instead.
*/
// TODO: Remove in Smack 4.5.
@Deprecated
default <F extends XmlElement> 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 <code>null</code> if the server doesn't support that feature.
@ -636,6 +591,7 @@ public interface XMPPConnection {
* @return a stanza extensions of the feature or <code>null</code>
* @since 4.4
*/
@SuppressWarnings("TypeParameterUnusedInFormals")
<F extends XmlElement> F getFeature(QName qname);
/**

View file

@ -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.
*/

View file

@ -301,7 +301,7 @@ public final class ModularXmppClientToServerConnection extends AbstractXMPPConne
currentStateVertex = StateDescriptorGraph.convertToStateGraph(initialStateDescriptorVertex, connectionInternal);
}
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"})
public <CM extends ModularXmppClientToServerConnectionModule<? extends ModularXmppClientToServerConnectionModuleDescriptor>> CM getConnectionModuleFor(
Class<? extends ModularXmppClientToServerConnectionModuleDescriptor> descriptorClass) {
return (CM) connectionModules.get(descriptorClass);
@ -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.
@ -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);
@ -666,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);
@ -707,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);
@ -817,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);
@ -849,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);
@ -892,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);
@ -899,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);
@ -954,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);
@ -994,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);
@ -1056,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);
@ -1077,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);

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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<UInt16> {

View file

@ -28,19 +28,20 @@ import org.jivesoftware.smack.util.ExceptionUtil;
* even block the thread since only one thread may print at a time.
* <p>
* 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 <code>printInterpreted</code> static variable to <code>true</code>.
* </p>
*
* @author Gaston Dombiak
*/
public class ConsoleDebugger extends AbstractDebugger {
private final SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss");
private final SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.S");
public ConsoleDebugger(XMPPConnection connection) {
super(connection);
}
@SuppressWarnings("JavaUtilDate")
@Override
protected void log(String logMessage) {
String formatedDate;

View file

@ -27,7 +27,7 @@ import org.jivesoftware.smack.XMPPConnection;
* even block the thread since only one thread may print at a time.
* <p>
* 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 <code>printInterpreted</code> static variable to <code>true</code>.
* </p>
*

View file

@ -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);
/**

View file

@ -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 <E extends ExtensionElement> NotFilter of(Class<E> extensionElementClass) {
ExtensionElementFilter<E> extensionElementFilter = new ExtensionElementFilter<>(extensionElementClass);
return new NotFilter(extensionElementFilter);
}
}

View file

@ -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());
}

View file

@ -23,7 +23,7 @@
* <li>{@link StanzaIdFilter}: filters for stanzas with a particular stanza ID</li>
* <li>{@link ToMatchesFilter}: filters for stanzas that are sent to a particular address</li>
* <li>{@link FromMatchesFilter}: filters for stanzas that are sent from a particular address</li>
* <li>{@link ExtensionElementFilter}: filters for stanzas that have a particular stanza exentsion element</li>
* <li>{@link ExtensionElementFilter}: filters for stanzas that have a particular stanza extension element</li>
* <li>{@link AndFilter}: implements the logical AND operation over two or more filters</li>
* <li>{@link OrFilter}: implements the logical OR operation over two or more filters</li>
* <li>{@link NotFilter}: implements the logical NOT operation on a filter</li>

View file

@ -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;
}

View file

@ -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.
@ -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<? extends StateDescriptor> inferredSuccessorOfInitialStateDescriptor : inferredForwardEdges.getAll(initialStatedescriptorClass)) {
initialNode.getElement().addSuccessor(inferredSuccessorOfInitialStateDescriptor);
}
@ -368,7 +368,7 @@ public class StateDescriptorGraph {
}
}
public static <E> void stateDescriptorGraphToDot(Collection<GraphVertex<StateDescriptor>> vertexes,
public static void stateDescriptorGraphToDot(Collection<GraphVertex<StateDescriptor>> vertexes,
PrintWriter dotOut, boolean breakStateName) {
dotOut.append("digraph {\n");
dfs(vertexes,

View file

@ -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<Exception> initialize() {
InputStream is = null;
final ClassLoader classLoader = this.getClass().getClassLoader();
final List<Exception> exceptions = new LinkedList<Exception>();
final List<Exception> exceptions = new ArrayList<Exception>();
final String providerUriString = getProvidersUri();
if (providerUriString != null) {
try {

View file

@ -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);
}

View file

@ -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 <PE> type of the ExtensionElement.
* @return the extension, or <code>null</code> if it doesn't exist.
*/
@SuppressWarnings("TypeParameterUnusedInFormals")
public <PE extends XmlElement> PE getExtension(String elementName, String namespace) {
return PacketUtil.extensionElementFrom(extensions, elementName, namespace);
}

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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.
* <p>
* 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.

View file

@ -88,14 +88,14 @@ public abstract class IQ extends Stanza implements IqView {
}
@Override
public Type getType() {
public final Type getType() {
return type;
}
/**
* Sets the type of the IQ packet.
* <p>
* 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
* <code>null</code>.
* </p>
*
@ -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;
@ -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());
}

View file

@ -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<String> mechanisms = new LinkedList<String>();
public final List<String> mechanisms = new ArrayList<String>();
public Mechanisms(String mechanism) {
mechanisms.add(mechanism);

View file

@ -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<MessageBuilder>
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<MessageBuilder>
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<Subject> 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<MessageBuilder>
return buf;
}
/**
* Creates and returns a copy of this message stanza.
* <p>
* This does not perform a deep clone, as extension elements are shared between the new and old
* instance.
* </p>
* @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.
*/

View file

@ -20,11 +20,6 @@ import org.jivesoftware.smack.XMPPConnection;
public abstract class MessageOrPresence<MPB extends MessageOrPresenceBuilder<?, ?>> extends Stanza {
@Deprecated
// TODO: Remove in Smack 4.5.
protected MessageOrPresence() {
}
protected MessageOrPresence(StanzaBuilder<?> stanzaBuilder) {
super(stanzaBuilder);
}

View file

@ -18,7 +18,7 @@
package org.jivesoftware.smack.packet;
/**
* A Nonza, i.e everything that is <b>not a stanza</b> as defined
* A Nonza, i.e. everything that is <b>not a stanza</b> as defined
* RFC 6120 8. Stanzas are {@link Message}, {@link Presence} and {@link IQ}.
* Everything else should sublcass this class instead of {@link Stanza}.
* <p>

View file

@ -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<PresenceBuilder>
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<PresenceBuilder>
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<PresenceBuilder>
* 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 <a href="https://tools.ietf.org/html/rfc6121#section-4.7.2.3">RFC 6121 § 4.7.2.3. Priority Element</a>
* @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<PresenceBuilder>
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<PresenceBuilder>
return buf;
}
/**
* Creates and returns a copy of this presence stanza.
* <p>
* This does not perform a deep clone, as extension elements are shared between the new and old
* instance.
* </p>
* @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

View file

@ -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);

View file

@ -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.
* <p>
* This is meant to construct extension elements used as simple flags in Stanzas.
* <p>
*
* @param name the name of the extension element.
* @param namespace the namespace of the extension element.

View file

@ -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;
@ -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.
*
@ -219,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;
}
@ -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<XmlElement> 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 <E> 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 <code>null</code> 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 extends ExtensionElement> 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<XmlElement> 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.
*/

View file

@ -87,9 +87,9 @@ public abstract class StanzaBuilder<B extends StanzaBuilder<B>> 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)

View file

@ -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 <code>null</code> if
* the value is not set. The XMPP protocol often makes the "to"
* attribute optional, so it does not always need to be set.<p>
* attribute optional, so it does not always need to be set.
*
* @return who the stanza is being sent to, or <code>null</code> 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 <code>null</code> if
* the value is not set. The XMPP protocol often makes the "from"
* attribute optional, so it does not always need to be set.<p>
* attribute optional, so it does not always need to be set.
*
* @return who the stanza is being sent from, or <code>null</code> if the
* value has not been set.

View file

@ -58,9 +58,9 @@ import org.jivesoftware.smack.util.XmlStringBuilder;
* stream has been authenticated </td></tr>
* <tr><td> policy-violation </td><td> the entity has violated some local service
* policy. </td></tr>
* <tr><td> remote-connection-failed </td><td> Rthe server is unable to properly connect
* <tr><td> remote-connection-failed </td><td> the server is unable to properly connect
* to a remote entity. </td></tr>
* <tr><td> resource-constraint </td><td> Rthe server lacks the system resources necessary
* <tr><td> resource-constraint </td><td> the server lacks the system resources necessary
* to service the stream. </td></tr>
* <tr><td> restricted-xml </td><td> the entity has attempted to send restricted XML
* features. </td></tr>

View file

@ -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) {
if (StringUtils.isEmpty(content)) {
xml.setEmptyElement();
} else {
xml.rightAngleBracket();
xml.escape(content);
}
return xml;
}
}

View file

@ -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<IQProviderInfo> iqProviders = new LinkedList<IQProviderInfo>();
private final Collection<ExtensionProviderInfo> extProviders = new LinkedList<ExtensionProviderInfo>();
private final Collection<StreamFeatureProviderInfo> sfProviders = new LinkedList<StreamFeatureProviderInfo>();
private final Collection<IQProviderInfo> iqProviders = new ArrayList<IQProviderInfo>();
private final Collection<ExtensionProviderInfo> extProviders = new ArrayList<ExtensionProviderInfo>();
private final Collection<StreamFeatureProviderInfo> sfProviders = new ArrayList<StreamFeatureProviderInfo>();
private List<Exception> exceptions = new LinkedList<Exception>();
private List<Exception> exceptions = new ArrayList<Exception>();
public ProviderFileLoader(InputStream providerStream) {
this(providerStream, ProviderFileLoader.class.getClassLoader());

View file

@ -97,6 +97,7 @@ import org.jivesoftware.smack.util.XmppElementUtil;
* &lt;/extensionProvider&gt;
* &lt;/smackProviders&gt;</pre>
*
* <p>
* 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.<p>
* attach it to the packet.
* </p>
*
* @author Matt Tucker
*/

View file

@ -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:
* <ul>

View file

@ -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);

View file

@ -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;

View file

@ -358,7 +358,7 @@ public abstract class SASLMechanism implements Comparable<SASLMechanism> {
* 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 <a href="http://tools.ietf.org/html/rfc4013">RFC 4013 - SASLprep: Stringprep Profile for User Names and Passwords</a>
*/
protected static String saslPrep(String string) {

View file

@ -271,6 +271,7 @@ public abstract class ScramMechanism extends SASLMechanism {
return null;
}
@SuppressWarnings("MixedMutabilityReturnType")
private static Map<Character, String> parseAttributes(String string) throws SmackSaslException {
if (string.length() == 0) {
return Collections.emptyMap();

View file

@ -55,6 +55,7 @@ public class CollectionUtil {
boolean test(T t);
}
@SuppressWarnings("NonApiType")
public static <T> ArrayList<T> newListWith(Collection<? extends T> collection) {
if (collection == null) {
return null;

View file

@ -1,6 +1,6 @@
/**
*
* Copyright 2014-2019 Florian Schmaus
* Copyright 2014-2023 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,10 +24,12 @@ public class LazyStringBuilder implements Appendable, CharSequence {
private final List<CharSequence> list;
private String cache;
private transient String cache;
private int cachedLength = -1;
private void invalidateCache() {
cache = null;
cachedLength = -1;
}
public LazyStringBuilder() {
@ -65,9 +67,10 @@ public class LazyStringBuilder implements Appendable, CharSequence {
@Override
public int length() {
if (cache != null) {
return cache.length();
if (cachedLength >= 0) {
return cachedLength;
}
int length = 0;
try {
for (CharSequence csq : list) {
@ -78,6 +81,8 @@ public class LazyStringBuilder implements Appendable, CharSequence {
StringBuilder sb = safeToStringBuilder();
throw new RuntimeException("The following LazyStringBuilder threw a NullPointerException: " + sb, npe);
}
cachedLength = length;
return length;
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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<K, V> {
}
/**
* 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<V> remove(K key, int num) {
List<V> values = map.get(key);
if (values == null) {

View file

@ -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".
*

View file

@ -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 extends Stanza> S parseStanza(String stanza) throws XmlPullParserException, SmackParsingException, IOException {
return (S) parseStanza(getParserFor(stanza), XmlEnvironment.EMPTY);
}
@ -230,7 +229,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. <body></body>, which appears to be valid XMPP, or a
// i.e. <body></body>, which appears to be valid XMPP, or a
// least it's not explicitly forbidden by RFC 6121 5.2.3
return "";
} else {
@ -644,7 +643,7 @@ public class PacketParserUtils {
assert parser.getEventType() == XmlPullParser.Event.START_ELEMENT;
String name;
final int initialDepth = parser.getDepth();
List<String> methods = new LinkedList<>();
List<String> methods = new ArrayList<>();
outerloop: while (true) {
XmlPullParser.Event eventType = parser.next();
switch (eventType) {
@ -850,7 +849,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 +863,7 @@ public class PacketParserUtils {
}
break;
case END_ELEMENT:
if (parser.getDepth() == initalDepth) {
if (parser.getDepth() == initialDepth) {
break outerloop;
}
break;

View file

@ -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 extends XmlElement> PE extensionElementFrom(Collection<XmlElement> collection,
String element, String namespace) {
for (XmlElement packetExtension : collection) {

View file

@ -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.
@ -26,11 +26,12 @@ public final class Pair<F, S> {
this.second = second;
}
public static <F extends Object, S extends Object> Pair<F, S> create(F first, S second) {
public static <F, S> Pair<F, S> create(F first, S second) {
return new Pair<>(first, second);
}
public static <F extends Object, S extends Object> Pair<F, S> createAndInitHashCode(F first, S second) {
@SuppressWarnings("ReturnValueIgnored")
public static <F, S> Pair<F, S> createAndInitHashCode(F first, S second) {
Pair<F, S> pair = new Pair<>(first, second);
pair.hashCode();
return pair;

View file

@ -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;
@ -146,7 +144,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
@ -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) {

View file

@ -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);
}

Some files were not shown because too many files have changed in this diff Show more