From 33671055523a2388d0abf110937d9d13d190ae10 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 12 Jun 2014 18:43:36 +0200 Subject: [PATCH 01/22] Smack 4.0.1-SNAPSHOT --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 8e86ec30d..b9b82cdec 100644 --- a/build.gradle +++ b/build.gradle @@ -5,8 +5,8 @@ allprojects { apply plugin: 'eclipse' ext { - shortVersion = '4.0.0' - isSnapshot = false + shortVersion = '4.0.1' + isSnapshot = true gitCommit = getGitCommit() javadocAllDir = new File(buildDir, 'javadoc') documentationDir = new File(projectDir, 'documentation') From 6e8b51c08804a9d655b3afb4e7e8c16cdfb93699 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 11 Jun 2014 16:16:59 +0200 Subject: [PATCH 02/22] Add missing 4.0.0 Changelog --- resources/releasedocs/changelog.html | 123 +++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/resources/releasedocs/changelog.html b/resources/releasedocs/changelog.html index 309e3a9c9..efe216bce 100644 --- a/resources/releasedocs/changelog.html +++ b/resources/releasedocs/changelog.html @@ -141,6 +141,129 @@ hr {
+

4.0.0 -- 2014-06-08

+ +

Sub-task +

+
    +
  • [SMACK-399] - Add support for Roster Versioning (was XEP-0237, now in RFC 6121) +
  • +
  • [SMACK-400] - Change xml-not-well-formed to not-well-formed +
  • +
  • [SMACK-401] - Remove <invalid-id/> +
  • +
  • [SMACK-445] - XMPPError class is based on deprecated XEP-0086 +
  • +
+ +

Bug +

+
    +
  • [SMACK-357] - Error in SASL authentication when SASL authzid parameter is null +
  • +
  • [SMACK-410] - Any valid SSL server certificate can be used to perform a man-in-the-middle attack +
  • +
  • [SMACK-411] - ServiceDiscoveryManager identities should be non-static and kept in a Set to allow multiple identities as per XEP-30 +
  • +
  • [SMACK-414] - Smack does not announce the support for XEP-54 aka vcard-temp +
  • +
  • [SMACK-427] - Typo in code - StreamInitiation.setSesssionID() +
  • +
  • [SMACK-467] - Don't use the default locale for machine-readable output, use Locale.US instead +
  • +
  • [SMACK-531] - Add missing namespace attribute to XHTML-IM body tags +
  • +
  • [SMACK-533] - Smack should prevent IQ response spoofing +
  • +
  • [SMACK-535] - jul.properties should only configure the 'org.igniterealtime' namespace +
  • +
  • [SMACK-538] - ParseRoster does not check the sender of the roster and for pending roster queries +
  • +
  • [SMACK-541] - XHTMLExtensionProvider relies on incorrect behavior of MXParser, violating the contract of the XMLPullParser interface +
  • +
  • [SMACK-543] - packet.Time is not thread-safe +
  • +
  • [SMACK-546] - PubSub's Item needs to escape its XML payload +
  • +
  • [SMACK-548] - PingManager notifies pingFailedListeners multiple times +
  • +
  • [SMACK-551] - ChatManager throws NPE, when Message has no 'from' attribute +
  • +
  • [SMACK-554] - Memory leak in BookmarkManager +
  • +
  • [SMACK-555] - VCardProvider should consider some elements as optional +
  • +
  • [SMACK-558] - connect() must wait until the stream features have been parsed +
  • +
  • [SMACK-559] - Roster entries without a group are not updated +
  • +
  • [SMACK-560] - Race condition in PacketWriter +
  • +
  • [SMACK-567] - XMPPConnection leaks listenerExecutor ExecutorService +
  • +
+ +

Improvement +

+
    +
  • [SMACK-343] - Make Smack jar an OSGi bundle. +
  • +
  • [SMACK-356] - There is no way to reliably end a Chat and have a new one created. +
  • +
  • [SMACK-454] - Follow XEP-0170 recommendation: Compression before Resource Binding +
  • +
  • [SMACK-459] - Add option to configure the default identity in ServiceDiscoveryManager +
  • +
  • [SMACK-465] - Replace custom wrapped Throwable in XMPPException with Exception.cause +
  • +
  • [SMACK-468] - Don't throw an IOException in IBBStreams when the stream got closed by the remote +
  • +
  • [SMACK-536] - JUL Loggers should become final +
  • +
  • [SMACK-537] - Move XMPP Ping code to smackx, add keep-alive functionality to PingManager +
  • +
  • [SMACK-545] - Change API to the style mentioned in Smack's Code Guidelines +
  • +
  • [SMACK-547] - Consistent behavior for "from" attribute on outgoing stanzas +
  • +
  • [SMACK-556] - Make ConnectionConfigration getters public +
  • +
  • [SMACK-557] - Provide a MultiUserChat method to create *or* join a room +
  • +
  • [SMACK-568] - Don't exclude groupchat messages without body element in MultiUserChat MessageListeners +
  • +
+ +

New Feature +

+
    +
  • [SMACK-53] - Add support for XEP-0092: Software Version +
  • +
  • [SMACK-71] - Create new FromFilter that checks for exact matching +
  • +
  • [SMACK-187] - Add HTTP Binding support (BOSH / XEP-0124) +
  • +
  • [SMACK-265] - Move to a newer build process with artifacts published to maven central repo +
  • +
  • [SMACK-426] - Improve XMPPException +
  • +
  • [SMACK-544] - Add support for XEP-0079: Advanced Message Processing +
  • +
  • [SMACK-552] - Add support for "HTTP over XMPP transport" aka. XEP-0332 +
  • +
+ +

Task +

+
    +
  • [SMACK-371] - Some MUC tasks are using stanza's as defined in an older version of the spec. Fails to work on some servers. +
  • +
  • [SMACK-432] - Code cleanup of deprecated methods +
  • +
  • [SMACK-446] - Remove non-SASL authentication code +
  • +
+

3.4.1 -- Feb 9, 2014

Bug

From 1de2da8ec485b69e2a6a5bf21ddb401399d61027 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 11 Jun 2014 16:17:34 +0200 Subject: [PATCH 03/22] Update README.html to point to "Smack 4 Readme and Upgrade Guide" DOC-2703 --- resources/releasedocs/README.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/releasedocs/README.html b/resources/releasedocs/README.html index 7807b4ae6..96d7fd5b4 100644 --- a/resources/releasedocs/README.html +++ b/resources/releasedocs/README.html @@ -163,7 +163,7 @@ that can be found in the "documentation" directory included with this distributi Further information can be found on the Smack website. If you need help using or would like to make contributions or fixes to the code, please visit the -online forum. +online forum.

About the Distribution

@@ -176,6 +176,7 @@ while smack-debug.jar contains an enhanced debugger.

View the changelog for a list of changes since the last release. +If you are upgrading from Smack 3 to Smack 4, then please consult the Smack 4 Readme and Upgrade Guide

License Agreements

    From 3d926a034ca114462bf429467cbea2ea27dc6042 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 11 Jun 2014 16:20:24 +0200 Subject: [PATCH 04/22] Fix documentation to use correct XMPPConnection names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some parts of the documentation still refer to Connection connection = new XMPPConnection(…) when it should be XMPPConnection connection = new XMPPTCPConnection(…) SMACK-574 --- documentation/connections.html | 8 ++++---- documentation/gettingstarted.html | 6 +++--- documentation/overview.html | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/documentation/connections.html b/documentation/connections.html index 081e70f1a..36fa17f2c 100644 --- a/documentation/connections.html +++ b/documentation/connections.html @@ -20,8 +20,8 @@

    The org.jivesoftware.smack.XMPPConnection class manages your connection to an XMPP - server. The default implementation is the org.jivesoftware.smack.XMPPConnection - class. Two constructors are mainly used. The first, XMPPConnection(String) takes + server. The default implementation is the org.jivesoftware.smack.XMPPTCPConnection + class. Two constructors are mainly used. The first, XMPPTCPConnection(String) takes the server name you'd like to connect to as an argument. All default connection settings will be used:

      @@ -33,7 +33,7 @@
    • The XMPP resource name "Smack" will be used for the connection.
    - Alternatively, you can use the XMPPServer(ConnectionConfiguration) constructor to + Alternatively, you can use the XMPPTCPConnection(ConnectionConfiguration) constructor to specify advanced connection settings. Some of these settings include:
      @@ -63,7 +63,7 @@ ConnectionConfiguration config = new ConnectionConfiguration(// Connect to the server connection.connect(); // Log into the server diff --git a/documentation/gettingstarted.html b/documentation/gettingstarted.html index 74b19f177..1e52551ee 100644 --- a/documentation/gettingstarted.html +++ b/documentation/gettingstarted.html @@ -76,18 +76,18 @@ list of initializers. Establishing a Connection

      -The XMPPConnection class is used to create a connection to an +The XMPPTCPConnection class is used to create a connection to an XMPP server. Below are code examples for making a connection:

       // Create a connection to the jabber.org server.
      -Connection conn1 = new XMPPConnection("jabber.org");
      +XMPPConnection conn1 = new XMPPTCPConnection("jabber.org");
       conn1.connect();
       
       // Create a connection to the jabber.org server on a specific port.
       ConnectionConfiguration config = new ConnectionConfiguration("jabber.org", 5222);
      -Connection conn2 = new XMPPConnection(config);
      +XMPPConnection conn2 = new XMPPTCPConnection(config);
       conn2.connect();
       
      diff --git a/documentation/overview.html b/documentation/overview.html index 6fa057727..619ec9575 100644 --- a/documentation/overview.html +++ b/documentation/overview.html @@ -28,7 +28,7 @@ Smack Key Advantages can be accomplished in only a few lines of code:
      -Connection connection = new XMPPConnection("jabber.org");
      +XMPPConnection connection = new XMPPTCPConnection("jabber.org");
       connection.connect();
       connection.login("mtucker", "password");
       Chat chat = connection.getChatManager().createChat("jsmith@jivesoftware.com", new MessageListener() {
      
      From 273c2d7da977af7429b058a9905624024ce2013f Mon Sep 17 00:00:00 2001
      From: Florian Schmaus 
      Date: Thu, 12 Jun 2014 16:12:04 +0200
      Subject: [PATCH 05/22] Fix PingManager, use 'nextPingIn' to schedule
      
      pings, instead of 'pingInterval'. Fixes SMACK-575.
      ---
       .../src/main/java/org/jivesoftware/smackx/ping/PingManager.java | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java
      index af201ff32..7f5d1a658 100644
      --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java
      +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java
      @@ -308,7 +308,7 @@ public class PingManager extends Manager {
                   int nextPingIn = pingInterval - delta;
                   LOGGER.fine("Scheduling ServerPingTask in " + nextPingIn + " seconds (pingInterval="
                                   + pingInterval + ", delta=" + delta + ")");
      -            nextAutomaticPing = schedule(pingServerRunnable, pingInterval, TimeUnit.SECONDS);
      +            nextAutomaticPing = schedule(pingServerRunnable, nextPingIn, TimeUnit.SECONDS);
               }
           }
       
      
      From eec0df386c7792df449919ab612f4f164686ed00 Mon Sep 17 00:00:00 2001
      From: Florian Schmaus 
      Date: Sat, 14 Jun 2014 11:45:38 +0200
      Subject: [PATCH 06/22] s/JEP/XEP/
      
      also s;jabber.org/jeps;xmpp.org/extensions;
      ---
       documentation/extensions/dataforms.html       |  2 +-
       documentation/extensions/disco.html           |  2 +-
       documentation/extensions/filetransfer.html    |  8 +++----
       documentation/extensions/intro.html           |  6 ++---
       documentation/extensions/invitation.html      |  4 ++--
       documentation/extensions/messageevents.html   |  2 +-
       documentation/extensions/muc.html             |  2 +-
       documentation/extensions/privatedata.html     |  2 +-
       documentation/extensions/rosterexchange.html  |  2 +-
       documentation/extensions/time.html            |  2 +-
       documentation/extensions/xhtml.html           |  2 +-
       .../jivesoftware/smackx/CompressionTest.java  |  2 +-
       .../smackx/MultipleRecipientManagerTest.java  |  2 +-
       .../smackx/OfflineMessageManagerTest.java     |  4 ++--
       .../address/MultipleRecipientManager.java     | 24 +++++++++----------
       .../smackx/bookmarks/BookmarkManager.java     |  4 ++--
       .../bookmarks/BookmarkedConference.java       |  2 +-
       .../smackx/bookmarks/BookmarkedURL.java       |  2 +-
       .../smackx/bookmarks/Bookmarks.java           |  2 +-
       .../filetransfer/FileTransferNegotiator.java  |  8 +++----
       .../smackx/filetransfer/StreamNegotiator.java |  2 +-
       .../smackx/iqprivate/PrivateDataManager.java  |  2 +-
       .../muc/packet/GroupChatInvitation.java       |  4 ++--
       .../smackx/muc/packet/MUCUser.java            |  2 +-
       .../smackx/search/SimpleUserSearch.java       |  2 +-
       .../smackx/search/UserSearchManager.java      |  2 +-
       .../smackx/vcardtemp/packet/VCard.java        |  4 ++--
       .../smackx/xhtmlim/packet/XHTMLExtension.java |  4 ++--
       .../extensions.providers                      |  2 +-
       .../smackx/jingle/packet/Jingle.java          |  4 ++--
       30 files changed, 56 insertions(+), 56 deletions(-)
      
      diff --git a/documentation/extensions/dataforms.html b/documentation/extensions/dataforms.html
      index 1c2aee457..cfc5b1f78 100644
      --- a/documentation/extensions/dataforms.html
      +++ b/documentation/extensions/dataforms.html
      @@ -15,7 +15,7 @@ tasks such as registration and searching using Forms.
         
    • Create a Form to fill out
    • Answer a Form
    -JEP related: JEP-4 +XEP related: XEP-4
    diff --git a/documentation/extensions/disco.html b/documentation/extensions/disco.html index 40a612bcb..1af4a5298 100644 --- a/documentation/extensions/disco.html +++ b/documentation/extensions/disco.html @@ -18,7 +18,7 @@ entities. Follow these links to learn how to use this extension.
  • Discover information about an XMPP entity
  • Publish publicly available items
-JEP related: JEP-30 +XEP related: XEP-30
diff --git a/documentation/extensions/filetransfer.html b/documentation/extensions/filetransfer.html index f71fcc5df..e4f36a4c6 100644 --- a/documentation/extensions/filetransfer.html +++ b/documentation/extensions/filetransfer.html @@ -17,10 +17,10 @@ The file transfer extension allows the user to transmit and receive files.
  • Recieving a file from another user
  • Monitoring the progress of a file transfer
  • -JEP related: JEP-95 -JEP-96 -JEP-65 -JEP-47 +XEP related: XEP-95 +XEP-96 +XEP-65 +XEP-47

    diff --git a/documentation/extensions/intro.html b/documentation/extensions/intro.html index 811ba9174..244edb334 100644 --- a/documentation/extensions/intro.html +++ b/documentation/extensions/intro.html @@ -32,17 +32,17 @@ Message Events - JEP-0022 + XEP-0022 Requests and responds to message events. Data Forms - JEP-0004 + XEP-0004 Allows to gather data using Forms. Multi User Chat - JEP-0045 + XEP-0045 Allows configuration of, participation in, and administration of individual text-based conference rooms. diff --git a/documentation/extensions/invitation.html b/documentation/extensions/invitation.html index c15b15824..6fbbf892c 100644 --- a/documentation/extensions/invitation.html +++ b/documentation/extensions/invitation.html @@ -17,8 +17,8 @@ users to a group chat room.

    -JEP related: N/A -- this protocol is outdated now that the Multi-User Chat (MUC) JEP is available -(JEP-45). However, most +XEP related: N/A -- this protocol is outdated now that the Multi-User Chat (MUC) XEP is available +(XEP-45). However, most existing clients still use this older protocol. Once MUC support becomes more widespread, this API may be deprecated. diff --git a/documentation/extensions/messageevents.html b/documentation/extensions/messageevents.html index d91492b3f..163a800a2 100644 --- a/documentation/extensions/messageevents.html +++ b/documentation/extensions/messageevents.html @@ -19,7 +19,7 @@ display, and composition of messages. There are three stages in this extension:<

  • Reacting to Event Notification Requests
  • Reacting to Event Notifications
  • -JEP related: JEP-22 +XEP related: XEP-22

    Description

    diff --git a/documentation/extensions/muc.html b/documentation/extensions/muc.html index f4e4877c8..54ce72fb0 100644 --- a/documentation/extensions/muc.html +++ b/documentation/extensions/muc.html @@ -22,7 +22,7 @@ Allows configuration of, participation in, and administration of individual text

  • Manage role modifications
  • Manage affiliation modifications
  • -JEP related: JEP-45 +XEP related: XEP-45
    diff --git a/documentation/extensions/privatedata.html b/documentation/extensions/privatedata.html index 4d0f65887..c90dff29f 100644 --- a/documentation/extensions/privatedata.html +++ b/documentation/extensions/privatedata.html @@ -19,7 +19,7 @@ XML namespace. Example private data: </color>

    -JEP related: JEP-49 +XEP related: XEP-49


    diff --git a/documentation/extensions/rosterexchange.html b/documentation/extensions/rosterexchange.html index e014da111..1bb8d7fc0 100644 --- a/documentation/extensions/rosterexchange.html +++ b/documentation/extensions/rosterexchange.html @@ -17,7 +17,7 @@ are received from other XMPP clients.
  • Send a roster's entry
  • Receive roster entries
  • -JEP related: JEP-93 +XEP related: XEP-93
    diff --git a/documentation/extensions/time.html b/documentation/extensions/time.html index 7c00efa77..800a26169 100644 --- a/documentation/extensions/time.html +++ b/documentation/extensions/time.html @@ -11,7 +11,7 @@ Supports a protocol that XMPP clients use to exchange their respective local times and time zones.

    -JEP related: JEP-90 +XEP related: XEP-90


    diff --git a/documentation/extensions/xhtml.html b/documentation/extensions/xhtml.html index f283f57ba..8cdee0d8d 100644 --- a/documentation/extensions/xhtml.html +++ b/documentation/extensions/xhtml.html @@ -18,7 +18,7 @@ XHTML messages:

  • Receive an XHTML Message
  • Discover support for XHTML Messages
  • -JEP related: JEP-71 +XEP related: XEP-71
    diff --git a/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/CompressionTest.java b/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/CompressionTest.java index 4b770ccc8..7e01e5f27 100644 --- a/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/CompressionTest.java +++ b/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/CompressionTest.java @@ -24,7 +24,7 @@ import org.jivesoftware.smack.test.SmackTestCase; import org.jivesoftware.smackx.packet.Version; /** - * Ensure that stream compression (JEP-138) is correctly supported by Smack. + * Ensure that stream compression (XEP-138) is correctly supported by Smack. * * @author Gaston Dombiak */ diff --git a/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/MultipleRecipientManagerTest.java b/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/MultipleRecipientManagerTest.java index 084869d82..62391edaa 100644 --- a/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/MultipleRecipientManagerTest.java +++ b/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/MultipleRecipientManagerTest.java @@ -30,7 +30,7 @@ import java.util.Arrays; import java.util.List; /** - * Tests that JEP-33 support in Smack is correct. + * Tests that XEP-33 support in Smack is correct. * * @author Gaston Dombiak */ diff --git a/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/OfflineMessageManagerTest.java b/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/OfflineMessageManagerTest.java index 40f6615d7..04a01e3c1 100644 --- a/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/OfflineMessageManagerTest.java +++ b/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/OfflineMessageManagerTest.java @@ -32,7 +32,7 @@ import java.util.List; /** * Tests handling of offline messaging using OfflineMessageManager. This server requires the - * server to support JEP-0013: Flexible Offline Message Retrieval. + * server to support XEP-0013: Flexible Offline Message Retrieval. * * @author Gaston Dombiak */ @@ -44,7 +44,7 @@ public class OfflineMessageManagerTest extends SmackTestCase { public void testDiscoverFlexibleRetrievalSupport() throws XMPPException { OfflineMessageManager offlineManager = new OfflineMessageManager(getConnection(1)); - assertTrue("Server does not support JEP-13", offlineManager.supportsFlexibleRetrieval()); + assertTrue("Server does not support XEP-13", offlineManager.supportsFlexibleRetrieval()); } /** diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientManager.java index d7819927f..3fe189fee 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientManager.java @@ -40,7 +40,7 @@ import java.util.logging.Logger; /** * A MultipleRecipientManager allows to send packets to multiple recipients by making use of - * JEP-33: Extended Stanza Addressing. + * XEP-33: Extended Stanza Addressing. * It also allows to send replies to packets that were sent to multiple recipients. * * @author Gaston Dombiak @@ -57,9 +57,9 @@ public class MultipleRecipientManager { /** * Sends the specified packet to the list of specified recipients using the - * specified connection. If the server has support for JEP-33 then only one + * specified connection. If the server has support for XEP-33 then only one * packet is going to be sent to the server with the multiple recipient instructions. - * However, if JEP-33 is not supported by the server then the client is going to send + * However, if XEP-33 is not supported by the server then the client is going to send * the packet to each recipient. * * @param connection the connection to use to send the packet. @@ -72,8 +72,8 @@ public class MultipleRecipientManager { * list exists. * @throws FeatureNotSupportedException if special XEP-33 features where requested, but the * server does not support them. - * @throws XMPPErrorException if server does not support JEP-33: Extended Stanza Addressing and - * some JEP-33 specific features were requested. + * @throws XMPPErrorException if server does not support XEP-33: Extended Stanza Addressing and + * some XEP-33 specific features were requested. * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException */ @@ -84,8 +84,8 @@ public class MultipleRecipientManager { /** * Sends the specified packet to the list of specified recipients using the specified - * connection. If the server has support for JEP-33 then only one packet is going to be sent to - * the server with the multiple recipient instructions. However, if JEP-33 is not supported by + * connection. If the server has support for XEP-33 then only one packet is going to be sent to + * the server with the multiple recipient instructions. However, if XEP-33 is not supported by * the server then the client is going to send the packet to each recipient. * * @param connection the connection to use to send the packet. @@ -99,8 +99,8 @@ public class MultipleRecipientManager { * @param replyRoom JID of a MUC room to which responses should be sent or null * indicating that they can reply to any address. * @param noReply true means that receivers should not reply to the message. - * @throws XMPPErrorException if server does not support JEP-33: Extended Stanza Addressing and - * some JEP-33 specific features were requested. + * @throws XMPPErrorException if server does not support XEP-33: Extended Stanza Addressing and + * some XEP-33 specific features were requested. * @throws NoResponseException if there was no response from the server. * @throws FeatureNotSupportedException if special XEP-33 features where requested, but the * server does not support them. @@ -115,10 +115,10 @@ public class MultipleRecipientManager { serviceAddress); } else { - // Server does not support JEP-33 so try to send the packet to each recipient + // Server does not support XEP-33 so try to send the packet to each recipient if (noReply || (replyTo != null && replyTo.trim().length() > 0) || (replyRoom != null && replyRoom.trim().length() > 0)) { - // Some specified JEP-33 features were requested so throw an exception alerting + // Some specified XEP-33 features were requested so throw an exception alerting // the user that this features are not available throw new FeatureNotSupportedException("Extended Stanza Addressing"); } @@ -191,7 +191,7 @@ public class MultipleRecipientManager { serviceAddress); } else { - // Server does not support JEP-33 so try to send the packet to each recipient + // Server does not support XEP-33 so try to send the packet to each recipient sendToIndividualRecipients(connection, reply, to, cc, null); } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkManager.java index 597b32ebf..4c3303503 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkManager.java @@ -34,10 +34,10 @@ import org.jivesoftware.smackx.iqprivate.PrivateDataManager; /** - * Provides methods to manage bookmarks in accordance with JEP-0048. Methods for managing URLs and + * Provides methods to manage bookmarks in accordance with XEP-0048. Methods for managing URLs and * Conferences are provided. *

    - * It should be noted that some extensions have been made to the JEP. There is an attribute on URLs + * It should be noted that some extensions have been made to the XEP. There is an attribute on URLs * that marks a url as a news feed and also a sub-element can be added to either a URL or conference * indicated that it is shared amongst all users on a server. * diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkedConference.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkedConference.java index 68e335b2e..0bbb1395e 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkedConference.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkedConference.java @@ -18,7 +18,7 @@ package org.jivesoftware.smackx.bookmarks; /** - * Respresents a Conference Room bookmarked on the server using JEP-0048 Bookmark Storage JEP. + * Respresents a Conference Room bookmarked on the server using XEP-0048 Bookmark Storage XEP. * * @author Derek DeMoro */ diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkedURL.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkedURL.java index 70e9d67fc..d00161add 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkedURL.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkedURL.java @@ -18,7 +18,7 @@ package org.jivesoftware.smackx.bookmarks; /** - * Respresents one instance of a URL defined using JEP-0048 Bookmark Storage JEP. + * Respresents one instance of a URL defined using XEP-0048 Bookmark Storage XEP. * * @author Derek DeMoro */ diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/Bookmarks.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/Bookmarks.java index f70de8a99..8d9d866fc 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/Bookmarks.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/Bookmarks.java @@ -27,7 +27,7 @@ import java.util.List; /** * Bookmarks is used for storing and retrieving URLS and Conference rooms. - * Bookmark Storage (JEP-0048) defined a protocol for the storage of bookmarks to conference rooms and other entities + * Bookmark Storage (XEP-0048) defined a protocol for the storage of bookmarks to conference rooms and other entities * in a Jabber user's account. * See the following code sample for saving Bookmarks: *

    diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java index 6b1c4cc16..0f59deec9 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java @@ -43,7 +43,7 @@ import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.packet.DataForm; /** - * Manages the negotiation of file transfers according to JEP-0096. If a file is + * Manages the negotiation of file transfers according to XEP-0096. If a file is * being sent the remote user chooses the type of stream under which the file * will be sent. * @@ -357,13 +357,13 @@ public class FileTransferNegotiator { * If they accept, the packet will contain the other user's chosen stream * type to send the file across. The two choices this implementation * provides to the other user for file transfer are SOCKS5 Bytestreams, + * href="http://www.xmpp.org/extensions/jep-0065.html">SOCKS5 Bytestreams, * which is the preferred method of transfer, and In-Band Bytestreams, + * href="http://www.xmpp.org/extensions/jep-0047.html">In-Band Bytestreams, * which is the fallback mechanism. *

    * The other user may choose to decline the file request if they do not - * desire the file, their client does not support JEP-0096, or if there are + * desire the file, their client does not support XEP-0096, or if there are * no acceptable means to transfer the file. *

    * Finally, if the other user does not respond this method will return null diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/StreamNegotiator.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/StreamNegotiator.java index a8b873a13..a46ec4166 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/StreamNegotiator.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/StreamNegotiator.java @@ -37,7 +37,7 @@ import java.io.OutputStream; /** * After the file transfer negotiation process is completed according to - * JEP-0096, the negotiation process is passed off to a particular stream + * XEP-0096, the negotiation process is passed off to a particular stream * negotiator. The stream negotiator will then negotiate the chosen stream and * return the stream to transfer the file. * diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/PrivateDataManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/PrivateDataManager.java index 120bdd3d5..70141eef2 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/PrivateDataManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/PrivateDataManager.java @@ -50,7 +50,7 @@ import java.util.WeakHashMap; * a {@link DefaultPrivateData} instance will be returned.

    * * Warning: this is an non-standard protocol documented by - * JEP-49. Because this is a + * XEP-49. Because this is a * non-standard protocol, it is subject to change. * * @author Matt Tucker diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/GroupChatInvitation.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/GroupChatInvitation.java index f7d807d8d..2b8422f29 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/GroupChatInvitation.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/GroupChatInvitation.java @@ -43,8 +43,8 @@ import org.xmlpull.v1.XmlPullParser; * // Create a packet collector or packet listeners using the filter... * * - * Note: this protocol is outdated now that the Multi-User Chat (MUC) JEP is available - * (JEP-45). However, most + * Note: this protocol is outdated now that the Multi-User Chat (MUC) XEP is available + * (XEP-45). However, most * existing clients still use this older protocol. Once MUC support becomes more * widespread, this API may be deprecated. * diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/MUCUser.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/MUCUser.java index 51460c018..00e91bc79 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/MUCUser.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/MUCUser.java @@ -520,7 +520,7 @@ public class MUCUser implements PacketExtension { /** * Status code assists in presenting notification messages. The following link provides the - * list of existing error codes (@link http://www.jabber.org/jeps/jep-0045.html#errorstatus). + * list of existing error codes (@link http://www.xmpp.org/extensions/jep-0045.html#errorstatus). * * @author Gaston Dombiak */ diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/search/SimpleUserSearch.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/search/SimpleUserSearch.java index 675bac4f2..e38481af0 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/search/SimpleUserSearch.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/search/SimpleUserSearch.java @@ -25,7 +25,7 @@ import java.util.ArrayList; import java.util.List; /** - * SimpleUserSearch is used to support the non-dataform type of JEP 55. This provides + * SimpleUserSearch is used to support the non-dataform type of XEP 55. This provides * the mechanism for allowing always type ReportedData to be returned by any search result, * regardless of the form of the data returned from the server. * diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/search/UserSearchManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/search/UserSearchManager.java index df552b584..170e9408a 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/search/UserSearchManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/search/UserSearchManager.java @@ -31,7 +31,7 @@ import java.util.Collection; import java.util.List; /** - * The UserSearchManager is a facade built upon Jabber Search Services (JEP-055) to allow for searching + * The UserSearchManager is a facade built upon Jabber Search Services (XEP-055) to allow for searching * repositories on a Jabber Server. This implementation allows for transparency of implementation of * searching (DataForms or No DataForms), but allows the user to simply use the DataForm model for both * types of support. diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/packet/VCard.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/packet/VCard.java index 0a368fb38..37c5b9882 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/packet/VCard.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/packet/VCard.java @@ -45,7 +45,7 @@ import org.jivesoftware.smackx.vcardtemp.VCardManager; * SMACK jabber library.

    *

    * You should refer to the - * JEP-54 documentation.

    + * XEP-54 documentation.

    *

    * Please note that this class is incomplete but it does provide the most commonly found * information in vCards. Also remember that VCard transfer is not a standard, and the protocol @@ -114,7 +114,7 @@ public class VCard extends IQ { private String photoBinval; /** - * Such as DESC ROLE GEO etc.. see JEP-0054 + * Such as DESC ROLE GEO etc.. see XEP-0054 */ private Map otherSimpleFields = new HashMap(); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xhtmlim/packet/XHTMLExtension.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xhtmlim/packet/XHTMLExtension.java index 30903dfda..996073818 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xhtmlim/packet/XHTMLExtension.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xhtmlim/packet/XHTMLExtension.java @@ -28,10 +28,10 @@ import java.util.List; * extension is only a subset of XHTML 1.0.

    * * The following link summarizes the requirements of XHTML IM: - * Valid tags.

    + * Valid tags.

    * * Warning: this is an non-standard protocol documented by - * JEP-71. Because this is a + * XEP-71. Because this is a * non-standard protocol, it is subject to change. * * @author Gaston Dombiak diff --git a/smack-extensions/src/main/resources/org.jivesoftware.smackx/extensions.providers b/smack-extensions/src/main/resources/org.jivesoftware.smackx/extensions.providers index 5388ede2c..ccb02cd13 100644 --- a/smack-extensions/src/main/resources/org.jivesoftware.smackx/extensions.providers +++ b/smack-extensions/src/main/resources/org.jivesoftware.smackx/extensions.providers @@ -172,7 +172,7 @@ org.jivesoftware.smackx.sharedgroups.packet.SharedGroupsInfo$Provider - + addresses http://jabber.org/protocol/address diff --git a/smack-jingle/src/main/java/org/jivesoftware/smackx/jingle/packet/Jingle.java b/smack-jingle/src/main/java/org/jivesoftware/smackx/jingle/packet/Jingle.java index 2869ed955..8ede2faaf 100644 --- a/smack-jingle/src/main/java/org/jivesoftware/smackx/jingle/packet/Jingle.java +++ b/smack-jingle/src/main/java/org/jivesoftware/smackx/jingle/packet/Jingle.java @@ -29,10 +29,10 @@ import java.util.List; * An Jingle sub-packet, which is used by XMPP clients to exchange info like * descriptions and transports.

    The following link summarizes the * requirements of Jingle IM: Valid tags. + * href="http://www.xmpp.org/extensions/jep-0166.html">Valid tags. *

    *

    Warning: this is an non-standard protocol documented by JEP-166. Because this is + * href="http://www.xmpp.org/extensions/jep-0166.html">XEP-166. Because this is * a non-standard protocol, it is subject to change. * * @author Alvaro Saurin From 02651c668f8ff40a9ae6fde7d051f7a38c260d95 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 17 Jun 2014 10:52:49 +0200 Subject: [PATCH 07/22] Improve HostAddress, make some members final also - add getException() - improve constructor logic --- .../smack/util/dns/HostAddress.java | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/dns/HostAddress.java b/smack-core/src/main/java/org/jivesoftware/smack/util/dns/HostAddress.java index f051805c4..7f55db598 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/dns/HostAddress.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/dns/HostAddress.java @@ -1,6 +1,6 @@ /** * - * Copyright 2013 Florian Schmaus + * Copyright © 2013-2014 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,8 +17,8 @@ package org.jivesoftware.smack.util.dns; public class HostAddress { - private String fqdn; - private int port; + private final String fqdn; + private final int port; private Exception exception; /** @@ -28,16 +28,8 @@ public class HostAddress { * @throws IllegalArgumentException If the fqdn is null. */ public HostAddress(String fqdn) { - if (fqdn == null) - throw new IllegalArgumentException("FQDN is null"); - if (fqdn.charAt(fqdn.length() - 1) == '.') { - this.fqdn = fqdn.substring(0, fqdn.length() - 1); - } - else { - this.fqdn = fqdn; - } // Set port to the default port for XMPP client communication - this.port = 5222; + this(fqdn, 5222); } /** @@ -48,11 +40,17 @@ public class HostAddress { * @throws IllegalArgumentException If the fqdn is null or port is out of valid range (0 - 65535). */ public HostAddress(String fqdn, int port) { - this(fqdn); + if (fqdn == null) + throw new IllegalArgumentException("FQDN is null"); if (port < 0 || port > 65535) throw new IllegalArgumentException( "Port must be a 16-bit unsiged integer (i.e. between 0-65535. Port was: " + port); - + if (fqdn.charAt(fqdn.length() - 1) == '.') { + this.fqdn = fqdn.substring(0, fqdn.length() - 1); + } + else { + this.fqdn = fqdn; + } this.port = port; } @@ -68,6 +66,10 @@ public class HostAddress { this.exception = e; } + public Exception getException() { + return this.exception; + } + @Override public String toString() { return fqdn + ":" + port; From 46f4a553e03d990873950370a4cf71286f8b51c2 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 17 Jun 2014 11:00:05 +0200 Subject: [PATCH 08/22] Add javadoc to SmackException.ConnectionException and HostAddress --- .../main/java/org/jivesoftware/smack/SmackException.java | 6 ++++++ .../org/jivesoftware/smack/util/dns/HostAddress.java | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/SmackException.java b/smack-core/src/main/java/org/jivesoftware/smack/SmackException.java index 33f89e927..61aea2c98 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SmackException.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SmackException.java @@ -122,6 +122,12 @@ public class SmackException extends Exception { } } + /** + * ConnectionException is thrown if Smack is unable to connect to all hosts of a given XMPP + * service. The failed hosts can be retrieved with + * {@link ConnectionException#getFailedAddresses()}, which will have the exception causing the + * connection failure set and retrievable with {@link HostAddress#getException()}. + */ public static class ConnectionException extends SmackException { /** diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/dns/HostAddress.java b/smack-core/src/main/java/org/jivesoftware/smack/util/dns/HostAddress.java index 7f55db598..9b34239e5 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/dns/HostAddress.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/dns/HostAddress.java @@ -16,6 +16,8 @@ */ package org.jivesoftware.smack.util.dns; +import org.jivesoftware.smack.SmackException.ConnectionException; + public class HostAddress { private final String fqdn; private final int port; @@ -66,6 +68,13 @@ public class HostAddress { this.exception = e; } + /** + * Retrieve the Exception that caused a connection failure to this HostAddress. Every + * HostAddress found in {@link ConnectionException} will have an Exception set, + * which can be retrieved with this method. + * + * @return the Exception causing this HostAddress to fail + */ public Exception getException() { return this.exception; } From a77adc018bbb949733455594d53603226856d164 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 17 Jun 2014 12:08:36 +0200 Subject: [PATCH 09/22] Enable linkSource, use and JavaSE javadoc for javadocAll --- build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.gradle b/build.gradle index b9b82cdec..302b00228 100644 --- a/build.gradle +++ b/build.gradle @@ -66,6 +66,9 @@ task javadocAll(type: Javadoc) { // Might need a classpath classpath = files(subprojects.collect {project -> project.sourceSets.main.compileClasspath}) + options.linkSource = true + options.use = true + options.links = ["http://docs.oracle.com/javase/$sourceCompatibility/docs/api/"] as String[] } import org.apache.tools.ant.filters.ReplaceTokens From 298822eaefab623426359446451280f2b2ff54d1 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 17 Jun 2014 18:01:36 +0200 Subject: [PATCH 10/22] Make smack-resolver-javax an OSGi ServiceComponent Fixes SMACK-576 --- build.gradle | 2 +- smack-core/build.gradle | 1 + .../smack/util/dns/javax/JavaxResolver.java | 29 +++++++++++++++---- .../smack-resolver-javax-components.xml | 6 ++++ 4 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 smack-resolver-javax/src/main/resources/org.jivesoftware.smack/smack-resolver-javax-components.xml diff --git a/build.gradle b/build.gradle index 302b00228..385ab9943 100644 --- a/build.gradle +++ b/build.gradle @@ -200,7 +200,7 @@ subprojects { } } -['smack-extensions', 'smack-experimental', 'smack-legacy'].each { name -> +['smack-resolver-javax', 'smack-extensions', 'smack-experimental', 'smack-legacy'].each { name -> project(":$name") { jar { manifest { diff --git a/smack-core/build.gradle b/smack-core/build.gradle index faa2a514f..128bd81af 100644 --- a/smack-core/build.gradle +++ b/smack-core/build.gradle @@ -29,6 +29,7 @@ task dnsJar(type: Jar) { from sourceSets.main.output include('org/jivesoftware/smack/util/dns/**') include('org/jivesoftware/smack/util/DNSUtil.class') + include('org/jivesoftware/smack/initializer/**') } artifacts { diff --git a/smack-resolver-javax/src/main/java/org/jivesoftware/smack/util/dns/javax/JavaxResolver.java b/smack-resolver-javax/src/main/java/org/jivesoftware/smack/util/dns/javax/JavaxResolver.java index 5b8ac03e4..78d0d4260 100644 --- a/smack-resolver-javax/src/main/java/org/jivesoftware/smack/util/dns/javax/JavaxResolver.java +++ b/smack-resolver-javax/src/main/java/org/jivesoftware/smack/util/dns/javax/JavaxResolver.java @@ -17,6 +17,7 @@ package org.jivesoftware.smack.util.dns.javax; import java.util.ArrayList; +import java.util.Collections; import java.util.Hashtable; import java.util.List; @@ -27,6 +28,7 @@ import javax.naming.directory.Attributes; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; +import org.jivesoftware.smack.initializer.SmackInitializer; import org.jivesoftware.smack.util.DNSUtil; import org.jivesoftware.smack.util.dns.DNSResolver; import org.jivesoftware.smack.util.dns.SRVRecord; @@ -37,7 +39,7 @@ import org.jivesoftware.smack.util.dns.SRVRecord; * @author Florian Schmaus * */ -public class JavaxResolver implements DNSResolver { +public class JavaxResolver implements DNSResolver, SmackInitializer { private static JavaxResolver instance; private static DirContext dirContext; @@ -52,24 +54,28 @@ public class JavaxResolver implements DNSResolver { } // Try to set this DNS resolver as primary one - DNSUtil.setDNSResolver(getInstance()); + setup(); } - private JavaxResolver() { + public JavaxResolver() { } - - public static DNSResolver getInstance() { + + public static synchronized DNSResolver getInstance() { if (instance == null && isSupported()) { instance = new JavaxResolver(); } return instance; } - + public static boolean isSupported() { return dirContext != null; } + public static void setup() { + DNSUtil.setDNSResolver(getInstance()); + } + @Override public List lookupSRVRecords(String name) throws NamingException { List res = new ArrayList(); @@ -93,4 +99,15 @@ public class JavaxResolver implements DNSResolver { } return res; } + + @Override + public List initialize() { + return initialize(null); + } + + @Override + public List initialize(ClassLoader classLoader) { + setup(); + return Collections.emptyList(); + } } diff --git a/smack-resolver-javax/src/main/resources/org.jivesoftware.smack/smack-resolver-javax-components.xml b/smack-resolver-javax/src/main/resources/org.jivesoftware.smack/smack-resolver-javax-components.xml new file mode 100644 index 000000000..13d9deabd --- /dev/null +++ b/smack-resolver-javax/src/main/resources/org.jivesoftware.smack/smack-resolver-javax-components.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file From 2ce76561804301b9c83d292af01f5e8ca30d16e3 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 18 Jun 2014 19:45:14 +0200 Subject: [PATCH 11/22] Fix PrivateDataResult.getChildElementXML() that method never worked correctly since 11 years, ie. the PrivateData was never added as element text. It's not surprisingly that this was not discovered in more then a decade, since Smack usually never *sends* those stanza but only receives them. But that's no reason to not fix it. :) --- .../org/jivesoftware/smackx/iqprivate/PrivateDataManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/PrivateDataManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/PrivateDataManager.java index 70141eef2..789e187cd 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/PrivateDataManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/PrivateDataManager.java @@ -285,7 +285,7 @@ public class PrivateDataManager extends Manager { StringBuilder buf = new StringBuilder(); buf.append(""); if (privateData != null) { - privateData.toXML(); + buf.append(privateData.toXML()); } buf.append(""); return buf.toString(); From 26b5bc0212544b3d24b113a7fa86aa15293d96d5 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 19 Jun 2014 11:48:01 +0200 Subject: [PATCH 12/22] Properly escape Bookmarks and FormField XML by using XmlStringBuilder. Fixes SMACK-577 Also extend LazyStringBuilder with a cache. And extend XmlStringBuilder with some more convenience methods. Move the ELEMENT and NAMESPACE definition from Form to DataForm, where it belongs. --- .../smack/util/LazyStringBuilder.java | 29 ++++++++-- .../smack/util/XmlStringBuilder.java | 33 +++++++++++ .../smackx/bookmarks/Bookmarks.java | 52 ++++++++--------- .../smackx/caps/EntityCapsManager.java | 5 +- .../smackx/iqprivate/packet/PrivateData.java | 2 +- .../org/jivesoftware/smackx/xdata/Form.java | 3 - .../jivesoftware/smackx/xdata/FormField.java | 56 +++++++++---------- .../smackx/xdata/packet/DataForm.java | 53 ++++++++++-------- .../FileTransferNegotiatorTest.java | 2 +- 9 files changed, 140 insertions(+), 95 deletions(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/LazyStringBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/util/LazyStringBuilder.java index 8aa834bbb..d7df08411 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/LazyStringBuilder.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/LazyStringBuilder.java @@ -22,13 +22,20 @@ import java.util.List; public class LazyStringBuilder implements Appendable, CharSequence { private final List list; - + + private String cache; + + private void invalidateCache() { + cache = null; + } + public LazyStringBuilder() { list = new ArrayList(20); } public LazyStringBuilder append(LazyStringBuilder lsb) { list.addAll(lsb.list); + invalidateCache(); return this; } @@ -36,6 +43,7 @@ public class LazyStringBuilder implements Appendable, CharSequence { public LazyStringBuilder append(CharSequence csq) { assert csq != null; list.add(csq); + invalidateCache(); return this; } @@ -43,17 +51,22 @@ public class LazyStringBuilder implements Appendable, CharSequence { public LazyStringBuilder append(CharSequence csq, int start, int end) { CharSequence subsequence = csq.subSequence(start, end); list.add(subsequence); + invalidateCache(); return this; } @Override public LazyStringBuilder append(char c) { list.add(Character.toString(c)); + invalidateCache(); return this; } @Override public int length() { + if (cache != null) { + return cache.length(); + } int length = 0; for (CharSequence csq : list) { length += csq.length(); @@ -63,6 +76,9 @@ public class LazyStringBuilder implements Appendable, CharSequence { @Override public char charAt(int index) { + if (cache != null) { + return cache.charAt(index); + } for (CharSequence csq : list) { if (index < csq.length()) { return csq.charAt(index); @@ -80,10 +96,13 @@ public class LazyStringBuilder implements Appendable, CharSequence { @Override public String toString() { - StringBuilder sb = new StringBuilder(length()); - for (CharSequence csq : list) { - sb.append(csq); + if (cache == null) { + StringBuilder sb = new StringBuilder(length()); + for (CharSequence csq : list) { + sb.append(csq); + } + cache = sb.toString(); } - return sb.toString(); + return cache; } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java index 109187ced..9a39338a4 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java @@ -168,6 +168,25 @@ public class XmlStringBuilder implements Appendable, CharSequence { return this; } + public XmlStringBuilder emptyElement(String element) { + halfOpenElement(element); + return closeEmptyElement(); + } + + public XmlStringBuilder condEmptyElement(boolean condition, String element) { + if (condition) { + emptyElement(element); + } + return this; + } + + public XmlStringBuilder condAttribute(boolean condition, String name, String value) { + if (condition) { + attribute(name, value); + } + return this; + } + @Override public XmlStringBuilder append(CharSequence csq) { assert csq != null; @@ -207,4 +226,18 @@ public class XmlStringBuilder implements Appendable, CharSequence { public String toString() { return sb.toString(); } + + @Override + public boolean equals(Object other) { + if (!(other instanceof XmlStringBuilder)) { + return false; + } + XmlStringBuilder otherXmlStringBuilder = (XmlStringBuilder) other; + return toString().equals(otherXmlStringBuilder.toString()); + } + + @Override + public int hashCode() { + return toString().hashCode(); + } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/Bookmarks.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/Bookmarks.java index 8d9d866fc..10fdb2c2d 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/Bookmarks.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bookmarks/Bookmarks.java @@ -16,6 +16,7 @@ */ package org.jivesoftware.smackx.bookmarks; +import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smackx.iqprivate.packet.PrivateData; import org.jivesoftware.smackx.iqprivate.provider.PrivateDataProvider; import org.xmlpull.v1.XmlPullParser; @@ -59,6 +60,9 @@ import java.util.List; */ public class Bookmarks implements PrivateData { + public static final String NAMESPACE = "storage:bookmarks"; + public static final String ELEMENT = "storage"; + private List bookmarkedURLS; private List bookmarkedConferences; @@ -145,7 +149,7 @@ public class Bookmarks implements PrivateData { * @return the element name. */ public String getElementName() { - return "storage"; + return ELEMENT; } /** @@ -154,28 +158,26 @@ public class Bookmarks implements PrivateData { * @return the namespace. */ public String getNamespace() { - return "storage:bookmarks"; + return NAMESPACE; } /** - * Returns the XML reppresentation of the PrivateData. + * Returns the XML representation of the PrivateData. * * @return the private data as XML. */ - public String toXML() { - StringBuilder buf = new StringBuilder(); - buf.append(""); + @Override + public XmlStringBuilder toXML() { + XmlStringBuilder buf = new XmlStringBuilder(); + buf.openElement(ELEMENT).xmlnsAttribute(NAMESPACE); for (BookmarkedURL urlStorage : getBookmarkedURLS()) { if(urlStorage.isShared()) { continue; } - buf.append(""); + buf.openElement("url").attribute("name", urlStorage.getName()).attribute("url", urlStorage.getURL()); + buf.condAttribute(urlStorage.isRss(), "rss", "true"); + buf.closeEmptyElement(); } // Add Conference additions @@ -183,26 +185,20 @@ public class Bookmarks implements PrivateData { if(conference.isShared()) { continue; } - buf.append(""); + buf.openElement("conference"); + buf.attribute("name", conference.getName()); + buf.attribute("autojoin", Boolean.toString(conference.isAutoJoin())); + buf.attribute("jid", conference.getJid()); + buf.rightAngelBracket(); - if (conference.getNickname() != null) { - buf.append("").append(conference.getNickname()).append(""); - } + buf.optElement("nick", conference.getNickname()); + buf.optElement("password", conference.getPassword()); - - if (conference.getPassword() != null) { - buf.append("").append(conference.getPassword()).append(""); - } - buf.append(""); + buf.closeElement("conference"); } - - buf.append(""); - return buf.toString(); + buf.closeElement(ELEMENT); + return buf; } /** diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java index 7ef889874..6bba70e3f 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java @@ -44,7 +44,6 @@ import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Feature; import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity; import org.jivesoftware.smackx.disco.packet.DiscoverItems.Item; -import org.jivesoftware.smackx.xdata.Form; import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.packet.DataForm; @@ -528,7 +527,7 @@ public class EntityCapsManager extends Manager { protected static boolean verifyPacketExtensions(DiscoverInfo info) { List foundFormTypes = new LinkedList(); for (PacketExtension pe : info.getExtensions()) { - if (pe.getNamespace().equals(Form.NAMESPACE)) { + if (pe.getNamespace().equals(DataForm.NAMESPACE)) { DataForm df = (DataForm) pe; for (FormField f : df.getFields()) { if (f.getVariable().equals("FORM_TYPE")) { @@ -561,7 +560,7 @@ public class EntityCapsManager extends Manager { if (md == null) return null; - DataForm extendedInfo = (DataForm) discoverInfo.getExtension(Form.ELEMENT, Form.NAMESPACE); + DataForm extendedInfo = (DataForm) discoverInfo.getExtension(DataForm.ELEMENT, DataForm.NAMESPACE); // 1. Initialize an empty string S ('sb' in this method). StringBuilder sb = new StringBuilder(); // Use StringBuilder as we don't diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/packet/PrivateData.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/packet/PrivateData.java index 0d0dee919..41d50b11b 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/packet/PrivateData.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/packet/PrivateData.java @@ -45,5 +45,5 @@ public interface PrivateData { * * @return the private data as XML. */ - public String toXML(); + public CharSequence toXML(); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/Form.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/Form.java index 2cfc311ac..06ec091b6 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/Form.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/Form.java @@ -49,9 +49,6 @@ public class Form { public static final String TYPE_CANCEL = "cancel"; public static final String TYPE_RESULT = "result"; - public static final String NAMESPACE = "jabber:x:data"; - public static final String ELEMENT = "x"; - private DataForm dataForm; /** diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/FormField.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/FormField.java index 1d40525cc..1e7ba1bd8 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/FormField.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/FormField.java @@ -17,7 +17,6 @@ package org.jivesoftware.smackx.xdata; -import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.XmlStringBuilder; import java.util.ArrayList; @@ -33,6 +32,8 @@ import java.util.List; */ public class FormField { + public static final String ELEMENT = "field"; + public static final String TYPE_BOOLEAN = "boolean"; public static final String TYPE_FIXED = "fixed"; public static final String TYPE_HIDDEN = "hidden"; @@ -263,25 +264,17 @@ public class FormField { } } - public String toXML() { + public XmlStringBuilder toXML() { XmlStringBuilder buf = new XmlStringBuilder(); - buf.append(""); + buf.optAttribute("label", getLabel()); + buf.optAttribute("var", getVariable()); + buf.optAttribute("type", getType()); + buf.rightAngelBracket(); // Add elements - if (getDescription() != null) { - buf.append("").append(getDescription()).append(""); - } - if (isRequired()) { - buf.append(""); - } + buf.optElement("desc", getDescription()); + buf.condEmptyElement(isRequired(), "required"); // Loop through all the values and append them to the string buffer for (String value : getValues()) { buf.element("value", value); @@ -290,8 +283,8 @@ public class FormField { for (Option option : getOptions()) { buf.append(option.toXML()); } - buf.append(""); - return buf.toString(); + buf.closeElement(ELEMENT); + return buf; } @Override @@ -320,8 +313,10 @@ public class FormField { */ public static class Option { + public static final String ELEMNT = "option"; + + private final String value; private String label; - private String value; public Option(String value) { this.value = value; @@ -355,19 +350,18 @@ public class FormField { return getLabel(); } - public String toXML() { - StringBuilder buf = new StringBuilder(); - buf.append(""); - // Add element - buf.append("").append(StringUtils.escapeForXML(getValue())).append(""); + xml.optAttribute("label", getLabel()); + xml.rightAngelBracket(); - buf.append(""); - return buf.toString(); + // Add element + xml.element("value", getValue()); + + xml.closeElement(ELEMENT); + return xml; } @Override diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/packet/DataForm.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/packet/DataForm.java index 6ee3d80b6..9090a370a 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/packet/DataForm.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/packet/DataForm.java @@ -18,7 +18,7 @@ package org.jivesoftware.smackx.xdata.packet; import org.jivesoftware.smack.packet.PacketExtension; -import org.jivesoftware.smackx.xdata.Form; +import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smackx.xdata.FormField; import java.util.ArrayList; @@ -33,6 +33,9 @@ import java.util.List; */ public class DataForm implements PacketExtension { + public static final String NAMESPACE = "jabber:x:data"; + public static final String ELEMENT = "x"; + private String type; private String title; private List instructions = new ArrayList(); @@ -120,11 +123,11 @@ public class DataForm implements PacketExtension { } public String getElementName() { - return Form.ELEMENT; + return ELEMENT; } public String getNamespace() { - return Form.NAMESPACE; + return NAMESPACE; } /** @@ -207,15 +210,15 @@ public class DataForm implements PacketExtension { return found; } - public String toXML() { - StringBuilder buf = new StringBuilder(); - buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append( - "\" type=\"" + getType() +"\">"); - if (getTitle() != null) { - buf.append("").append(getTitle()).append(""); - } + @Override + public XmlStringBuilder toXML() { + XmlStringBuilder buf = new XmlStringBuilder(this); + buf.attribute("type", getType()); + buf.rightAngelBracket(); + + buf.optElement("title", getTitle()); for (String instruction : getInstructions()) { - buf.append("").append(instruction).append(""); + buf.element("instructions", instruction); } // Append the list of fields returned from a search if (getReportedData() != null) { @@ -229,8 +232,8 @@ public class DataForm implements PacketExtension { for (FormField field : getFields()) { buf.append(field.toXML()); } - buf.append(""); - return buf.toString(); + buf.closeElement(this); + return buf; } /** @@ -241,6 +244,8 @@ public class DataForm implements PacketExtension { * @author Gaston Dombiak */ public static class ReportedData { + public static final String ELEMENT = "reported"; + private List fields = new ArrayList(); public ReportedData(List fields) { @@ -256,15 +261,15 @@ public class DataForm implements PacketExtension { return Collections.unmodifiableList(new ArrayList(fields)); } - public String toXML() { - StringBuilder buf = new StringBuilder(); - buf.append(""); + public CharSequence toXML() { + XmlStringBuilder buf = new XmlStringBuilder(); + buf.openElement(ELEMENT); // Loop through all the form items and append them to the string buffer for (FormField field : getFields()) { buf.append(field.toXML()); } - buf.append(""); - return buf.toString(); + buf.closeElement(ELEMENT); + return buf; } } @@ -275,6 +280,8 @@ public class DataForm implements PacketExtension { * @author Gaston Dombiak */ public static class Item { + public static final String ELEMENT = "item"; + private List fields = new ArrayList(); public Item(List fields) { @@ -290,15 +297,15 @@ public class DataForm implements PacketExtension { return Collections.unmodifiableList(new ArrayList(fields)); } - public String toXML() { - StringBuilder buf = new StringBuilder(); - buf.append(""); + public CharSequence toXML() { + XmlStringBuilder buf = new XmlStringBuilder(); + buf.openElement(ELEMENT); // Loop through all the form items and append them to the string buffer for (FormField field : getFields()) { buf.append(field.toXML()); } - buf.append(""); - return buf.toString(); + buf.closeElement(ELEMENT); + return buf; } } } diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiatorTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiatorTest.java index f98b99887..ac4bad49f 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiatorTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiatorTest.java @@ -51,6 +51,6 @@ public class FileTransferNegotiatorTest { fileNeg.negotiateOutgoingTransfer("me", "streamid", "file", 1024, null, 10); Packet packet = connection.getSentPacket(); String xml = packet.toXML().toString(); - assertTrue(xml.indexOf("var='stream-method' type=\"list-single\"") != -1); + assertTrue(xml.indexOf("var='stream-method' type='list-single'") != -1); } } From 56222d6ee2d186e222ad8804472ea7570b4c03ef Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 18 Jun 2014 09:06:48 +0200 Subject: [PATCH 13/22] Improve parseContent() and parseContentDepth() The idea is that xml-roundtrip should *never* be expected from a XmlPullParser. So what we need is a method that parses the content of an element without relying on getText() returning text if on START_TAG or END_TAG. This is already done by PubSubs ItemProvider. Also add PacketParserUtils.parseElement() which will return the current element as String and use this method in PubSub's ItemProvider. --- .../smack/util/PacketParserUtils.java | 174 ++++++++++++++++-- .../org/jivesoftware/smack/RosterTest.java | 13 +- .../smack/parsing/ParsingExceptionTest.java | 15 +- .../smack/test/util/TestUtils.java | 20 +- .../smack/util/PacketParserUtilsTest.java | 32 ++-- .../cache/SimpleDirectoryPersistentCache.java | 5 +- .../smackx/pubsub/provider/ItemProvider.java | 55 +----- .../jivesoftware/smack/tcp/PacketReader.java | 4 +- 8 files changed, 201 insertions(+), 117 deletions(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java index aec0a2dbe..28be0b191 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java @@ -44,6 +44,7 @@ import org.jivesoftware.smack.provider.ProviderManager; import org.jivesoftware.smack.sasl.SASLMechanism.SASLFailure; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; /** * Utility class that helps to parse packets. Any parsing packets method that must be shared @@ -54,6 +55,24 @@ import org.xmlpull.v1.XmlPullParserException; public class PacketParserUtils { private static final Logger LOGGER = Logger.getLogger(PacketParserUtils.class.getName()); + /** + * Creates a new XmlPullParser suitable for parsing XMPP. This means in particular that + * FEATURE_PROCESS_NAMESPACES is enabled. + *

    + * Note that not all XmlPullParser implementations will return a String on + * getText() if the parser is on START_TAG or END_TAG. So you must not rely on this + * behavior when using the parser. + *

    + * + * @return A suitable XmlPullParser for XMPP parsing + * @throws XmlPullParserException + */ + public static XmlPullParser newXmppParser() throws XmlPullParserException { + XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser(); + parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); + return parser; + } + /** * Parses a message packet. * @@ -96,7 +115,7 @@ public class PacketParserUtils { xmlLang = defaultLanguage; } - String subject = parseContent(parser); + String subject = parseElementText(parser); if (message.getSubject(xmlLang) == null) { message.addSubject(xmlLang, subject); @@ -108,8 +127,8 @@ public class PacketParserUtils { xmlLang = defaultLanguage; } - String body = parseContent(parser); - + String body = parseElementText(parser); + if (message.getBody(xmlLang) == null) { message.addBody(xmlLang, body); } @@ -140,29 +159,156 @@ public class PacketParserUtils { } /** - * Returns the content of a tag as string regardless of any tags included. + * Returns the textual content of an element as String. + *

    + * The parser must be positioned on a START_TAG of an element which MUST NOT contain Mixed + * Content (as defined in XML 3.2.2), or else an XmlPullParserException will be thrown. + *

    + * This method is used for the parts where the XMPP specification requires elements that contain + * only text or are the empty element. + * + * @param parser + * @return the textual content of the element as String + * @throws XmlPullParserException + * @throws IOException + */ + public static String parseElementText(XmlPullParser parser) throws XmlPullParserException, IOException { + assert (parser.getEventType() == XmlPullParser.START_TAG); + String res; + if (parser.isEmptyElementTag()) { + res = ""; + } + else { + // Advance to the text of the Element + int event = parser.next(); + if (event != XmlPullParser.TEXT) { + throw new XmlPullParserException( + "Non-empty element tag not followed by text, while Mixed Content (XML 3.2.2) is disallowed"); + } + res = parser.getText(); + event = parser.next(); + if (event != XmlPullParser.END_TAG) { + throw new XmlPullParserException( + "Non-empty element tag contains child-elements, while Mixed Content (XML 3.2.2) is disallowed"); + } + } + return res; + } + + /** + * Returns the current element as string. + *

    + * The parser must be positioned on START_TAG. + *

    + * Note that only the outermost namespace attributes ("xmlns") will be returned, not nested ones. + * + * @param parser the XML pull parser + * @return the element as string + * @throws XmlPullParserException + * @throws IOException + */ + public static String parseElement(XmlPullParser parser) throws XmlPullParserException, IOException { + assert(parser.getEventType() == XmlPullParser.START_TAG); + return parseContentDepth(parser, parser.getDepth()); + } + + /** + * Returns the content of a element as string. + *

    + * The parser must be positioned on the START_TAG of the element which content is going to get + * returned. If the current element is the empty element, then the empty string is returned. If + * it is a element which contains just text, then just the text is returned. If it contains + * nested elements (and text), then everything from the current opening tag to the corresponding + * closing tag of the same depth is returned as String. + *

    + * Note that only the outermost namespace attributes ("xmlns") will be returned, not nested ones. * * @param parser the XML pull parser * @return the content of a tag as string * @throws XmlPullParserException if parser encounters invalid XML * @throws IOException if an IO error occurs */ - private static String parseContent(XmlPullParser parser) + public static String parseContent(XmlPullParser parser) throws XmlPullParserException, IOException { - int parserDepth = parser.getDepth(); - return parseContentDepth(parser, parserDepth); + assert(parser.getEventType() == XmlPullParser.START_TAG); + if (parser.isEmptyElementTag()) { + return ""; + } + // Advance the parser, since we want to parse the content of the current element + parser.next(); + return parseContentDepth(parser, parser.getDepth()); } + /** + * Returns the content from the current position of the parser up to the closing tag of the + * given depth. Note that only the outermost namespace attributes ("xmlns") will be returned, + * not nested ones. + *

    + * This method is able to parse the content with MX- and KXmlParser. In order to achieve + * this some trade-off has to be make, because KXmlParser does not support xml-roundtrip (ie. + * return a String on getText() on START_TAG and END_TAG). We are therefore required to work + * around this limitation, which results in only partial support for XML namespaces ("xmlns"): + * Only the outermost namespace of elements will be included in the resulting String. + *

    + * + * @param parser + * @param depth + * @return the content of the current depth + * @throws XmlPullParserException + * @throws IOException + */ public static String parseContentDepth(XmlPullParser parser, int depth) throws XmlPullParserException, IOException { - StringBuilder content = new StringBuilder(); - while (!(parser.next() == XmlPullParser.END_TAG && parser.getDepth() == depth)) { - String text = parser.getText(); - if (text == null) { - throw new IllegalStateException("Parser should never return 'null' on getText() here"); + XmlStringBuilder xml = new XmlStringBuilder(); + int event = parser.getEventType(); + boolean isEmptyElement = false; + // XmlPullParser reports namespaces in nested elements even if *only* the outer ones defines + // it. This 'flag' ensures that when a namespace is set for an element, it won't be set again + // in a nested element. It's an ugly workaround that has the potential to break things. + String namespaceElement = null;; + while (true) { + if (event == XmlPullParser.START_TAG) { + xml.halfOpenElement(parser.getName()); + if (namespaceElement == null) { + String namespace = parser.getNamespace(); + if (StringUtils.isNotEmpty(namespace)) { + xml.attribute("xmlns", namespace); + namespaceElement = parser.getName(); + } + } + for (int i = 0; i < parser.getAttributeCount(); i++) { + xml.attribute(parser.getAttributeName(i), parser.getAttributeValue(i)); + } + if (parser.isEmptyElementTag()) { + xml.closeEmptyElement(); + isEmptyElement = true; + } + else { + xml.rightAngelBracket(); + } } - content.append(text); + else if (event == XmlPullParser.END_TAG) { + if (isEmptyElement) { + // Do nothing as the element was already closed, just reset the flag + isEmptyElement = false; + } + else { + xml.closeElement(parser.getName()); + } + if (namespaceElement != null && namespaceElement.equals(parser.getName())) { + // We are on the closing tag, which defined the namespace as starting tag, reset the 'flag' + namespaceElement = null; + } + if (parser.getDepth() <= depth) { + // Abort parsing, we are done + break; + } + } + else if (event == XmlPullParser.TEXT) { + xml.append(parser.getText()); + } + event = parser.next(); } - return content.toString(); + return xml.toString(); } /** diff --git a/smack-core/src/test/java/org/jivesoftware/smack/RosterTest.java b/smack-core/src/test/java/org/jivesoftware/smack/RosterTest.java index 27e00253e..41e354745 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/RosterTest.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/RosterTest.java @@ -19,7 +19,6 @@ package org.jivesoftware.smack; import static org.junit.Assert.*; -import java.io.StringReader; import java.util.Collection; import java.util.Collections; import java.util.concurrent.CopyOnWriteArrayList; @@ -31,11 +30,11 @@ import org.jivesoftware.smack.packet.RosterPacket; import org.jivesoftware.smack.packet.IQ.Type; import org.jivesoftware.smack.packet.RosterPacket.Item; import org.jivesoftware.smack.packet.RosterPacket.ItemType; +import org.jivesoftware.smack.test.util.TestUtils; import org.jivesoftware.smack.util.PacketParserUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.xmlpull.v1.XmlPullParserFactory; import org.xmlpull.v1.XmlPullParser; /** @@ -315,8 +314,6 @@ public class RosterTest { final String contactJID = "nurse@example.com"; final Roster roster = connection.getRoster(); assertNotNull("Can't get the roster from the provided connection!", roster); - final XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); final StringBuilder sb = new StringBuilder(); sb.append("") @@ -324,8 +321,7 @@ public class RosterTest { .append("") .append("") .append(""); - parser.setInput(new StringReader(sb.toString())); - parser.next(); + final XmlPullParser parser = TestUtils.getIQParser(sb.toString()); final IQ rosterPush = PacketParserUtils.parseIQ(parser, connection); initRoster(connection, roster); rosterListener.reset(); @@ -449,8 +445,6 @@ public class RosterTest { final String contactJID = "nurse@example.com"; final Roster roster = connection.getRoster(); assertNotNull("Can't get the roster from the provided connection!", roster); - final XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); final StringBuilder sb = new StringBuilder(); sb.append("") @@ -460,8 +454,7 @@ public class RosterTest { .append("") .append("") .append(""); - parser.setInput(new StringReader(sb.toString())); - parser.next(); + final XmlPullParser parser = TestUtils.getIQParser(sb.toString()); final IQ rosterPush = PacketParserUtils.parseIQ(parser, connection); initRoster(connection, roster); rosterListener.reset(); diff --git a/smack-core/src/test/java/org/jivesoftware/smack/parsing/ParsingExceptionTest.java b/smack-core/src/test/java/org/jivesoftware/smack/parsing/ParsingExceptionTest.java index ee058887e..ebf801c23 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/parsing/ParsingExceptionTest.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/parsing/ParsingExceptionTest.java @@ -35,7 +35,7 @@ public class ParsingExceptionTest { private final static String EXTENSION2 = "" + "" + - "" + + "" + "" + "" + ""; @@ -52,12 +52,14 @@ public class ParsingExceptionTest { @Test public void consumeUnparsedInput() throws Exception { + final String MESSAGE_EXCEPTION_ELEMENT = + "<" + ThrowException.ELEMENT + " xmlns='" + ThrowException.NAMESPACE + "'>" + + "" + + "" + + ""; XmlPullParser parser = TestUtils.getMessageParser( "" + - "<" + ThrowException.ELEMENT + " xmlns='" + ThrowException.NAMESPACE + "'>" + - "" + - "" + - "" + + MESSAGE_EXCEPTION_ELEMENT + EXTENSION2 + ""); int parserDepth = parser.getDepth(); @@ -68,8 +70,7 @@ public class ParsingExceptionTest { content = PacketParserUtils.parseContentDepth(parser, parserDepth); } assertNotNull(content); - assertEquals(content, "" + "" + EXTENSION2); - + assertEquals(MESSAGE_EXCEPTION_ELEMENT + EXTENSION2 + "", content); } static class ThrowException implements PacketExtensionProvider { diff --git a/smack-core/src/test/java/org/jivesoftware/smack/test/util/TestUtils.java b/smack-core/src/test/java/org/jivesoftware/smack/test/util/TestUtils.java index ebfca81af..d5d4d7c5d 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/test/util/TestUtils.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/test/util/TestUtils.java @@ -17,9 +17,10 @@ package org.jivesoftware.smack.test.util; import java.io.IOException; +import java.io.Reader; import java.io.StringReader; -import org.xmlpull.v1.XmlPullParserFactory; +import org.jivesoftware.smack.util.PacketParserUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -39,12 +40,18 @@ final public class TestUtils { return getParser(stanza, "presence"); } - public static XmlPullParser getParser(String stanza, String startTag) { + public static XmlPullParser getParser(String string, String startTag) { + return getParser(new StringReader(string), startTag); + } + + public static XmlPullParser getParser(Reader reader, String startTag) { XmlPullParser parser; try { - parser = XmlPullParserFactory.newInstance().newPullParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - parser.setInput(new StringReader(stanza)); + parser = PacketParserUtils.newXmppParser(); + parser.setInput(reader); + if (startTag == null) { + return parser; + } boolean found = false; while (!found) { @@ -53,8 +60,7 @@ final public class TestUtils { } if (!found) - throw new IllegalArgumentException("Cannot parse start tag [" + startTag + "] from stanza [" + stanza - + "]"); + throw new IllegalArgumentException("Can not find start tag '" + startTag + "'"); } catch (XmlPullParserException e) { throw new RuntimeException(e); } catch (IOException e) { diff --git a/smack-core/src/test/java/org/jivesoftware/smack/util/PacketParserUtilsTest.java b/smack-core/src/test/java/org/jivesoftware/smack/util/PacketParserUtilsTest.java index 80436300f..39e484ee2 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/util/PacketParserUtilsTest.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/util/PacketParserUtilsTest.java @@ -27,7 +27,6 @@ import static org.junit.Assert.fail; import java.util.Locale; import java.util.Properties; -import org.custommonkey.xmlunit.DetailedDiff; import org.custommonkey.xmlunit.Diff; import org.custommonkey.xmlunit.examples.RecursiveElementNameAndTextQualifier; import org.jivesoftware.smack.packet.Message; @@ -654,7 +653,13 @@ public class PacketParserUtilsTest { } - @Test + /** + * RFC6121 5.2.3 explicitly disallows mixed content in elements. Make sure that we throw + * an exception if we encounter such an element. + * + * @throws Exception + */ + @Test(expected=XmlPullParserException.class) public void invalidMessageBodyContainingTagTest() throws Exception { String control = XMLBuilder.create("message") .a("from", "romeo@montague.lit/orchard") @@ -668,23 +673,10 @@ public class PacketParserUtilsTest { .a("style", "font-weight: bold;") .t("Bad Message Body") .asString(outputProperties); - - try { - Message message = (Message) PacketParserUtils.parseMessage(TestUtils.getMessageParser(control)); - String body = "" - + "Bad Message Body"; - assertEquals(body, message.getBody()); - - assertXMLNotEqual(control, message.toXML().toString()); - - DetailedDiff diffs = new DetailedDiff(new Diff(control, message.toXML().toString())); - - // body has no namespace URI, span is escaped - assertEquals(6, diffs.getAllDifferences().size()); - } catch(XmlPullParserException e) { - fail("No parser exception should be thrown" + e.getMessage()); - } - + + Message message = (Message) PacketParserUtils.parseMessage(TestUtils.getMessageParser(control)); + + fail("Should throw exception. Instead got message: " + message.toXML().toString()); } @Test @@ -794,7 +786,7 @@ public class PacketParserUtilsTest { public void parseContentDepthTest() throws Exception { final String stanza = ""; XmlPullParser parser = TestUtils.getParser(stanza, "iq"); - String content = PacketParserUtils.parseContentDepth(parser, 1); + String content = PacketParserUtils.parseContent(parser); assertEquals("", content); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/cache/SimpleDirectoryPersistentCache.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/cache/SimpleDirectoryPersistentCache.java index c8d90e1a2..1e9b538a5 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/cache/SimpleDirectoryPersistentCache.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/cache/SimpleDirectoryPersistentCache.java @@ -30,11 +30,11 @@ import java.util.logging.Logger; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smack.util.Base32Encoder; +import org.jivesoftware.smack.util.PacketParserUtils; import org.jivesoftware.smack.util.StringEncoder; import org.jivesoftware.smackx.caps.EntityCapsManager; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.provider.DiscoverInfoProvider; -import org.xmlpull.v1.XmlPullParserFactory; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -159,8 +159,7 @@ public class SimpleDirectoryPersistentCache implements EntityCapsPersistentCache Reader reader = new StringReader(fileContent); XmlPullParser parser; try { - parser = XmlPullParserFactory.newInstance().newPullParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); + parser = PacketParserUtils.newXmppParser(); parser.setInput(reader); } catch (XmlPullParserException xppe) { LOGGER.log(Level.SEVERE, "Exception initializing parser", xppe); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java index 6968e99ac..3dc3b1cb7 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java @@ -20,7 +20,6 @@ import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.provider.PacketExtensionProvider; import org.jivesoftware.smack.provider.ProviderManager; import org.jivesoftware.smack.util.PacketParserUtils; -import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smackx.pubsub.Item; import org.jivesoftware.smackx.pubsub.PayloadItem; import org.jivesoftware.smackx.pubsub.SimplePayload; @@ -41,7 +40,6 @@ public class ItemProvider implements PacketExtensionProvider { String id = parser.getAttributeValue(null, "id"); String node = parser.getAttributeValue(null, "node"); - String elem = parser.getName(); int tag = parser.next(); @@ -56,57 +54,8 @@ public class ItemProvider implements PacketExtensionProvider if (ProviderManager.getExtensionProvider(payloadElemName, payloadNS) == null) { - boolean done = false; - boolean isEmptyElement = false; - StringBuilder payloadText = new StringBuilder(); - - while (!done) - { - if (tag == XmlPullParser.END_TAG && parser.getName().equals(elem)) - { - done = true; - continue; - } - else if (parser.getEventType() == XmlPullParser.START_TAG) - { - payloadText.append("<").append(parser.getName()); - - if (parser.getName().equals(payloadElemName) && (payloadNS.length() > 0)) - payloadText.append(" xmlns=\"").append(payloadNS).append("\""); - int n = parser.getAttributeCount(); - - for (int i = 0; i < n; i++) - payloadText.append(" ").append(parser.getAttributeName(i)).append("=\"") - .append(parser.getAttributeValue(i)).append("\""); - - if (parser.isEmptyElementTag()) - { - payloadText.append("/>"); - isEmptyElement = true; - } - else - { - payloadText.append(">"); - } - } - else if (parser.getEventType() == XmlPullParser.END_TAG) - { - if (isEmptyElement) - { - isEmptyElement = false; - } - else - { - payloadText.append(""); - } - } - else if (parser.getEventType() == XmlPullParser.TEXT) - { - payloadText.append(StringUtils.escapeForXML(parser.getText())); - } - tag = parser.next(); - } - return new PayloadItem(id, node, new SimplePayload(payloadElemName, payloadNS, payloadText.toString())); + String payloadText = PacketParserUtils.parseElement(parser); + return new PayloadItem(id, node, new SimplePayload(payloadElemName, payloadNS, payloadText)); } else { diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/PacketReader.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/PacketReader.java index f40ac5dd3..b5bf1f192 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/PacketReader.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/PacketReader.java @@ -33,7 +33,6 @@ import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.SmackException.SecurityRequiredException; import org.jivesoftware.smack.XMPPException.StreamErrorException; -import org.xmlpull.v1.XmlPullParserFactory; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -131,8 +130,7 @@ class PacketReader { */ private void resetParser() throws SmackException { try { - parser = XmlPullParserFactory.newInstance().newPullParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); + parser = PacketParserUtils.newXmppParser(); parser.setInput(connection.getReader()); } catch (XmlPullParserException e) { From 1d21285d242bdbfefe6b29f8172959ce65bcd51d Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 22 Jun 2014 22:44:00 +0200 Subject: [PATCH 14/22] Update JIRA URL --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 385ab9943..42c3f7a1b 100644 --- a/build.gradle +++ b/build.gradle @@ -153,7 +153,7 @@ subprojects { issueManagement { system 'JIRA' - url 'http://issues.igniterealtime.org/browse/SMACK' + url 'https://igniterealtime.org/issues/browse/SMACK' } distributionManagement { From 1f6d0fa415d77e0ccae41af69eec3592db8eee64 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 22 Jun 2014 23:14:11 +0200 Subject: [PATCH 15/22] Use BufferedReader to read version --- .../org/jivesoftware/smack/SmackConfiguration.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java b/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java index 34a8c6ace..f666b9d48 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java @@ -17,8 +17,10 @@ package org.jivesoftware.smack; +import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; @@ -95,10 +97,13 @@ public final class SmackConfiguration { static { String smackVersion; try { - InputStream is = FileUtils.getStreamForUrl("classpath:org.jivesoftware.smack/version", null); - byte[] buf = new byte[1024]; - is.read(buf); - smackVersion = new String(buf, "UTF-8"); + BufferedReader reader = new BufferedReader(new InputStreamReader(FileUtils.getStreamForUrl("classpath:org.jivesoftware.smack/version", null))); + smackVersion = reader.readLine(); + try { + reader.close(); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "IOException closing stream", e); + } } catch(Exception e) { LOGGER.log(Level.SEVERE, "Could not determine Smack version", e); smackVersion = "unkown"; From 609c22586514a435db19977e75b45e0936cf1264 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 22 Jun 2014 22:35:38 +0200 Subject: [PATCH 16/22] Add smack-resolver-minidns --- build.gradle | 1 + settings.gradle | 1 + .../smack/SmackConfiguration.java | 4 + .../org/jivesoftware/smack/util/DNSUtil.java | 27 ++++++ smack-resolver-minidns/build.gradle | 10 +++ .../util/dns/minidns/MiniDnsResolver.java | 84 +++++++++++++++++++ 6 files changed, 127 insertions(+) create mode 100644 smack-resolver-minidns/build.gradle create mode 100644 smack-resolver-minidns/src/main/java/org/jivesoftware/smack/util/dns/minidns/MiniDnsResolver.java diff --git a/build.gradle b/build.gradle index 42c3f7a1b..2e0f5e76b 100644 --- a/build.gradle +++ b/build.gradle @@ -19,6 +19,7 @@ allprojects { sonatypeStagingUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' buildDate = (new java.text.SimpleDateFormat("yyyy-MM-dd")).format(new Date()) oneLineDesc = 'An Open Source XMPP (Jabber) client library' + jxmppVersion = "0.1.0-alpha1-SNAPSHOT" } group = 'org.igniterealtime.smack' sourceCompatibility = 1.7 diff --git a/settings.gradle b/settings.gradle index 39b03c03d..eefb8bac3 100644 --- a/settings.gradle +++ b/settings.gradle @@ -4,6 +4,7 @@ include 'smack-core', 'smack-experimental', 'smack-debug', 'smack-resolver-dnsjava', + 'smack-resolver-minidns', 'smack-resolver-javax', 'smack-compression-jzlib', 'smack-legacy', diff --git a/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java b/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java index f666b9d48..2b51cd69e 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java @@ -36,6 +36,7 @@ import org.jivesoftware.smack.compression.XMPPInputOutputStream; import org.jivesoftware.smack.initializer.SmackInitializer; import org.jivesoftware.smack.parsing.ExceptionThrowingCallback; import org.jivesoftware.smack.parsing.ParsingExceptionCallback; +import org.jivesoftware.smack.util.DNSUtil; import org.jivesoftware.smack.util.FileUtils; import org.xmlpull.v1.XmlPullParserFactory; import org.xmlpull.v1.XmlPullParser; @@ -167,6 +168,9 @@ public final class SmackConfiguration { catch (Exception e) { // Ignore. } + + // Initialize the DNS resolvers + DNSUtil.init(); } /** diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/DNSUtil.java b/smack-core/src/main/java/org/jivesoftware/smack/util/DNSUtil.java index 0027e7a85..dcd2d60de 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/DNSUtil.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/DNSUtil.java @@ -16,6 +16,8 @@ */ package org.jivesoftware.smack.util; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; @@ -39,6 +41,31 @@ public class DNSUtil { private static final Logger LOGGER = Logger.getLogger(DNSUtil.class.getName()); private static DNSResolver dnsResolver = null; + /** + * Initializes DNSUtil. This method is automatically called by SmackConfiguration, you don't + * have to call it manually. + */ + public static void init() { + final String[] RESOLVERS = new String[] { "javax.JavaxResolver", "minidns.MiniDnsResolver", + "dnsjava.DNSJavaResolver" }; + for (String resolver :RESOLVERS) { + DNSResolver availableResolver = null; + String resolverFull = "org.jivesoftware.smack.util.dns" + resolver; + try { + Class resolverClass = Class.forName(resolverFull); + Method getInstanceMethod = resolverClass.getMethod("getInstance"); + availableResolver = (DNSResolver) getInstanceMethod.invoke(null); + if (availableResolver != null) { + setDNSResolver(availableResolver); + break; + } + } + catch (ClassNotFoundException|NoSuchMethodException|SecurityException|IllegalAccessException|IllegalArgumentException|InvocationTargetException e) { + LOGGER.log(Level.FINE, "Exception on init", e); + } + } + } + /** * Set the DNS resolver that should be used to perform DNS lookups. * diff --git a/smack-resolver-minidns/build.gradle b/smack-resolver-minidns/build.gradle new file mode 100644 index 000000000..e707bb7c5 --- /dev/null +++ b/smack-resolver-minidns/build.gradle @@ -0,0 +1,10 @@ +description = """\ +DNS SRV with minidns +Use minidns for DNS SRV lookups. For platforms that don't provide the +javax.naming API (e.g. Android).""" + +dependencies { + compile project(path: ':smack-core', configuration: 'dns') + compile 'de.measite.minidns:minidns:0.1.1' + compile "org.igniterealtime.jxmpp:jxmpp-util-cache:$jxmppVersion" +} diff --git a/smack-resolver-minidns/src/main/java/org/jivesoftware/smack/util/dns/minidns/MiniDnsResolver.java b/smack-resolver-minidns/src/main/java/org/jivesoftware/smack/util/dns/minidns/MiniDnsResolver.java new file mode 100644 index 000000000..b290e96b2 --- /dev/null +++ b/smack-resolver-minidns/src/main/java/org/jivesoftware/smack/util/dns/minidns/MiniDnsResolver.java @@ -0,0 +1,84 @@ +/** + * + * Copyright 2014 Florian Schmaus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smack.util.dns.minidns; + +import java.util.LinkedList; +import java.util.List; + +import org.jivesoftware.smack.util.dns.DNSResolver; +import org.jivesoftware.smack.util.dns.SRVRecord; +import org.jxmpp.util.cache.ExpirationCache; + +import de.measite.minidns.Client; +import de.measite.minidns.DNSCache; +import de.measite.minidns.DNSMessage; +import de.measite.minidns.Question; +import de.measite.minidns.Record; +import de.measite.minidns.Record.CLASS; +import de.measite.minidns.Record.TYPE; +import de.measite.minidns.record.SRV; + + +/** + * This implementation uses the minidns implementation for + * resolving DNS addresses. + */ +public class MiniDnsResolver implements DNSResolver { + + private static final long ONE_DAY = 24*60*60*1000; + private static final MiniDnsResolver instance = new MiniDnsResolver(); + private static final ExpirationCache cache = new ExpirationCache(10, ONE_DAY); + private final Client client; + + private MiniDnsResolver() { + client = new Client(new DNSCache() { + + @Override + public DNSMessage get(Question question) { + return cache.get(question); + } + + @Override + public void put(Question question, DNSMessage message) { + long expirationTime = ONE_DAY; + for (Record record : message.getAnswers()) { + if (record.isAnswer(question)) { + expirationTime = record.getTtl(); + break; + } + } + cache.put(question, message, expirationTime); + } + + }); + } + + public static DNSResolver getInstance() { + return instance; + } + + @Override + public List lookupSRVRecords(String name) { + List res = new LinkedList(); + DNSMessage message = client.query(name, TYPE.SRV, CLASS.IN); + for (Record record : message.getAnswers()) { + SRV srv = (SRV) record.getPayload(); + res.add(new SRVRecord(srv.getName(), srv.getPort(), srv.getPriority(), srv.getWeight())); + } + return res; + } +} From 73c64dc06a28c0a848ddc1ee600cf7fa46b80c7f Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 22 Jun 2014 18:18:04 +0200 Subject: [PATCH 17/22] Record some more useful attributes in manifest --- build.gradle | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2e0f5e76b..22005f976 100644 --- a/build.gradle +++ b/build.gradle @@ -36,7 +36,12 @@ allprojects { // first occurence of an dash with a dot. // For example 4.0.0-rc1 becomes 4.0.0.rc1, but // 4.0.0-SNAPSHOT-2014-05-01 becomes 4.0.0.SNAPSHOT-2014-05-01 - 'Bundle-Version': version.replaceFirst("-", ".")) + 'Bundle-Version': version.replaceFirst("-", "."), + 'Built-Date': new Date(), + 'Built-JDK': System.getProperty('java.version'), + 'Built-Gradle': gradle.gradleVersion, + 'Built-By': System.getProperty('user.name') + ) } eclipse { From f39519dbbe1f872678f22c95c041b2c7d986e36a Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 26 Jun 2014 22:44:31 +0200 Subject: [PATCH 18/22] Disable uploadArchives for the root project --- build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.gradle b/build.gradle index 22005f976..97211eff2 100644 --- a/build.gradle +++ b/build.gradle @@ -102,6 +102,9 @@ jar { enabled = false } +// Disable upload archives for the root project +uploadArchives.enabled = false + description = """\ Smack ${version} ${oneLineDesc}.""" From 0f7365bc8a9441f32f7c4341a24049ff28103e98 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 26 Jun 2014 22:58:47 +0200 Subject: [PATCH 19/22] Use jxmpp 0.1.0 (non-SNAPSHOT) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 97211eff2..f75ca0458 100644 --- a/build.gradle +++ b/build.gradle @@ -19,7 +19,7 @@ allprojects { sonatypeStagingUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2' buildDate = (new java.text.SimpleDateFormat("yyyy-MM-dd")).format(new Date()) oneLineDesc = 'An Open Source XMPP (Jabber) client library' - jxmppVersion = "0.1.0-alpha1-SNAPSHOT" + jxmppVersion = "0.1.0" } group = 'org.igniterealtime.smack' sourceCompatibility = 1.7 From 1fb8a50b798c97da09a2244c8a28190411bfb037 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 27 Jun 2014 08:41:32 +0200 Subject: [PATCH 20/22] Improve documentation remove ambiguous part about smack-core being the only required library. It's the only required library of *Smack*, but some user could understand that Smack itself has no other dependencies. In order to avoid such confusion, simply remove that part. --- documentation/gettingstarted.html | 5 ++--- resources/releasedocs/README.html | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/documentation/gettingstarted.html b/documentation/gettingstarted.html index 1e52551ee..ee5c35273 100644 --- a/documentation/gettingstarted.html +++ b/documentation/gettingstarted.html @@ -29,8 +29,8 @@ to be as small as possible. The library ships as several JAR files to provide mo over which features applications require:
      -
    • smack-core.jar -- provides core XMPP functionality and is the only required - library. All XMPP features that are part of the XMPP RFCs are included.
    • +
    • smack-core.jar -- provides core XMPP functionality. All XMPP features that are + part of the XMPP RFCs are included.
    • smack-extensions.jar -- support for many of the extensions (XEPs) defined by the XMPP Standards Foundation, including multi-user chat, file transfer, user search, etc. The extensions are documented in the extensions manual.
    • @@ -52,7 +52,6 @@ over which features applications require: is enabled.
    -

    Configuration

    Smack has an initialization process that involves 2 phases.
      diff --git a/resources/releasedocs/README.html b/resources/releasedocs/README.html index 96d7fd5b4..d1a220e4c 100644 --- a/resources/releasedocs/README.html +++ b/resources/releasedocs/README.html @@ -167,8 +167,7 @@ fixes to the code, please visit the

      About the Distribution

      -The smack.jar file in the main distribution folder is the only binary file -required for embedding XMPP functionality into client applications. The optional +The smack-core.jar file in the main distribution folder. The optional smack-extensions.jar contains the Smack extensions while smack-debug.jar contains an enhanced debugger.

      From 08a232bff38b5ada278bab11647b633b36fef4c6 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 27 Jun 2014 12:22:45 +0200 Subject: [PATCH 21/22] Only include the jars of the actual version in distirbutionZip in order to avoid that other artifactss from previous builds slip in the distribution zip. --- build.gradle | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index f75ca0458..3365469cd 100644 --- a/build.gradle +++ b/build.gradle @@ -200,7 +200,9 @@ subprojects { rootProject.distributionZip { dependsOn build from(buildDir) { - include "$libsDirName/**" + include "$libsDirName/*${version}.jar" + include "$libsDirName/*${version}-javadoc.jar" + include "$libsDirName/*${version}-sources.jar" } } signing { From 4477561d4b0e59c7479eeae87e103cfcb5407342 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 5 Jul 2014 12:04:40 +0200 Subject: [PATCH 22/22] Replace references to 'smack.jar' Also don't mention the required JDK version in the README as such information tends to become wrong easily. --- documentation/debugging.html | 6 +++--- resources/README.html | 4 ++-- .../java/org/jivesoftware/smack/SmackConfiguration.java | 3 +-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/documentation/debugging.html b/documentation/debugging.html index 59e7d1cb2..b5f891a6d 100644 --- a/documentation/debugging.html +++ b/documentation/debugging.html @@ -16,8 +16,8 @@ Debugging with Smack

      Smack includes two built-in debugging consoles that will let you track all XML traffic between -the client and server. A lite debugger which is part of the smack.jar -and an enhanced debugger contained in smackx-debug.jar. +the client and server. A lite debugger which is part of the smack-core.jar +and an enhanced debugger contained in smack-debug.jar.

      @@ -56,7 +56,7 @@ Smack uses the following logic to decide the debugger console to use:

    • If step 1 fails then Smack will try to use the enhanced debugger. The file smackx-debug.jar contains the enhanced debugger. Therefore you will need to place the jar file in the classpath. For situations where space is an issue you - may want to only deploy smack.jar in which case the enhanced debugger won't be + may want to only deploy smack-core.jar in which case the enhanced debugger won't be available.

    • The last option if the previous two steps fail is to use the lite debugger. The lite diff --git a/resources/README.html b/resources/README.html index bd1895657..7d6e349e1 100644 --- a/resources/README.html +++ b/resources/README.html @@ -55,9 +55,9 @@ possible, instructions are provided for both Unix/Linux and Windows users.

      Configure Java

        - Java 6 (JDK 1.6 or later) must be installed and setup on your machine. To test the installation, + A Java Development Kit (JDK) must be installed and setup on your machine. To test the installation, open a shell in a Unix or a MS-DOS prompt in Windows. Check your version of - Java with "java -version". + Java with "javac -version". If Java isn't installed, download a copy from the Java website.
      diff --git a/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java b/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java index 2b51cd69e..374c1c8b5 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java @@ -52,8 +52,7 @@ import org.xmlpull.v1.XmlPullParserException; * via the API will override settings in the configuration file. *
    * - * Configuration settings are stored in org.jivesoftware.smack/smack-config.xml (typically inside the - * smack.jar file). + * Configuration settings are stored in org.jivesoftware.smack/smack-config.xml. * * @author Gaston Dombiak */