This is actually only part one, i.e. with this commit if the user adds a
PacketExtension to an IQ it will be included in IQ.toXml(). Which was
previously only the case if the IQ subclass explicitly included packet
extensions.
The second part of the change is to change the IQ provider, so that
packet extensions are automatically parsed.
Cases where PacketExtensions are used for Message and IQ are slightly
changed. The IQ sublcass now only has a field with this
PacketExtension (see for example
bytestreams.ibb.packet.DataPacketExtension).
Also changed hoxt API: Removed unnecessary indirection and made the
API more Smack idiomatic.
Remove the synchronized, as getExtensions() is properly synchronized and will
return a copy.
Return XmlStringBuilder instead of CharSequence to take advantage of
fast XmlStringBuilder.append(XmlStringBuilder).
Mark the method as final, as it should not be overwritten.
to keep the order in which the elements are added.
Some XEPs define a Schema using 'xs:sequence' (see for example XEP-60 §
17.1), so the order the PacketExtensions are added should be the same
they are transformed to a XML String.
In order to prevent
<iq to='...' from='...' type='result' id='1'>
<mynode xmlns='my:namespace' myattr='...'>
<somenode\>
</mynode>
</iq>
showing up as UnparsedResultIQ like this:
<iq to='...' from='...' type='result' id='1'>
<somenode\>
</iq>
Also make executorService a non-ScheduledExecutorService. This was an
artifact from times where executorService as used to schedule
Runnables. But now it's just used to queue the receive packets in
Runnables and call the packet collectors and listeners.
Those where never correctly implemented and are not really used. If you
want to compare Packets, compare their toXML() result.
N.B. that we keep hashCode/equals for Message.(Subject|Body) because
those are correct and are in-use ('bodies' and 'subjects' are Sets in
Message).
allowing O(1) lookups for PacketExtensions
The one EntityCapsManagerTest becomes obsolete with this change, as
duplicate extension elements (RFC 6120 § 8.4) are now no longer possible
after the stanza has been parsed (they still may be received on the
wire, but only the last duplicate will be added).
sendListeners are now invoked *after* the packet has been put on the
wire.
Also sending listener exceptions are not catched and not only
NotConnectedExceptions. And a exception does not cause a 'break' but a
'continue' now. Log level is WARNING now.
Thanks to Stefan Karlsson for helping with the implementation.
Also add SASLMechanism.checkIfSuccessfulOrThrow(), to increase the
security by verifying the mechanisms state at the end of SASL
authentication.
SASLMechanism now has a SASLPrep StringTransformer.
Refactor SHA1 functions out of StringUtils into SHA1 utility class.
Add MAC utility class.
Make DummyConnection getSentpacket() methods use generics to make unit
testing SCRAM-SHA1 easier.
Fixes SMACK-398
If a user enabled Smack debug via the property 'smack.debugEnabled', a
ConnectionConfiguration could be created where debuggerEnabled is
'false', because Smack is not yet initialized.
Also make sure that if the property is not set, it won't overwrite
DEBUG_ENABLED = true.
Thanks to William Murphy for providing a detailed issue description and
supposing a fix.
As otherwise there would be multiple log statements (which are of level
fine but nevertheless).
PacketParserUtils: XmlPullParser does not support XML_ROUNDTRIP org.xmlpull.v1.XmlPullParserException: unsupported feature: http://xmlpull.org/v1/doc/features.html#xml-roundtrip (position:START_DOCUMENT null@1:1)
PacketParserUtils: at org.kxml2.io.KXmlParser.setFeature(KXmlParser.java:2091)
PacketParserUtils: at org.jivesoftware.smack.util.PacketParserUtils.newXmppParser(PacketParserUtils.java:150)
PacketParserUtils: at org.jivesoftware.smack.util.PacketParserUtils.newXmppParser(PacketParserUtils.java:172)
PacketParserUtils: at org.jivesoftware.smack.tcp.XMPPTCPConnection.openStream(XMPPTCPConnection.java:963)
PacketParserUtils: at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketWriter.access$2600(XMPPTCPConnection.java:1224)
PacketParserUtils: at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketWriter$1.run(XMPPTCPConnection.java:1263)
PacketParserUtils: XmlPullParser does not support XML_ROUNDTRIP org.xmlpull.v1.XmlPullParserException: unsupported feature: http://xmlpull.org/v1/doc/features.html#xml-roundtrip (position:START_DOCUMENT null@1:1)
PacketParserUtils: at org.kxml2.io.KXmlParser.setFeature(KXmlParser.java:2091)
PacketParserUtils: at org.jivesoftware.smack.util.PacketParserUtils.newXmppParser(PacketParserUtils.java:150)
PacketParserUtils: at org.jivesoftware.smack.util.PacketParserUtils.newXmppParser(PacketParserUtils.java:172)
PacketParserUtils: at org.jivesoftware.smack.tcp.XMPPTCPConnection.openStream(XMPPTCPConnection.java:963)
PacketParserUtils: at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$200(XMPPTCPConnection.java:970)
PacketParserUtils: at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:989)
PacketParserUtils: XmlPullParser does not support XML_ROUNDTRIP org.xmlpull.v1.XmlPullParserException: unsupported feature: http://xmlpull.org/v1/doc/features.html#xml-roundtrip (position:START_DOCUMENT null@1:1)
PacketParserUtils: at org.kxml2.io.KXmlParser.setFeature(KXmlParser.java:2091)
PacketParserUtils: at org.jivesoftware.smack.util.PacketParserUtils.newXmppParser(PacketParserUtils.java:150)
PacketParserUtils: at org.jivesoftware.smack.util.PacketParserUtils.newXmppParser(PacketParserUtils.java:172)
PacketParserUtils: at org.jivesoftware.smack.tcp.XMPPTCPConnection.openStream(XMPPTCPConnection.java:963)
PacketParserUtils: at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$200(XMPPTCPConnection.java:970)
PacketParserUtils: at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:989)
PacketParserUtils: XmlPullParser does not support XML_ROUNDTRIP org.xmlpull.v1.XmlPullParserException: unsupported feature: http://xmlpull.org/v1/doc/features.html#xml-roundtrip (position:START_DOCUMENT null@1:1)
PacketParserUtils: at org.kxml2.io.KXmlParser.setFeature(KXmlParser.java:2091)
PacketParserUtils: at org.jivesoftware.smack.util.PacketParserUtils.newXmppParser(PacketParserUtils.java:150)
PacketParserUtils: at org.jivesoftware.smack.util.PacketParserUtils.newXmppParser(PacketParserUtils.java:172)
PacketParserUtils: at org.jivesoftware.smack.tcp.XMPPTCPConnection.openStream(XMPPTCPConnection.java:963)
PacketParserUtils: at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$200(XMPPTCPConnection.java:970)
PacketParserUtils: at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:989)
The approach to avoid XmlPullParser's XML_ROUNDTRIP feature prevents
Smack from handling XML namespaces on e.g. PubSub payloads on platforms
where support for XML_ROUNDTRIP would be available.
We now check for this XmlPullParser feature and use it if it's
available.
Using
createPacketCollector(filter);
sendPacket(packet);
was error prone, i.e. the PacketCollector could leak if sendPacket()
would throw an exception and the user forgot to call
PacketCollector.cancel(). For cases where
createPacketCollectorAndSend(IQ) is not sufficient (because we don't
send IQs), createPacketCollectorAndSend(PacketFilter, Packet) is now
used, which does take care that the PacketCollector does not leak if
sendPacket() throws an Exception.
Use PresenceListener as intercepting callback interface.
Remove the for-each loops in MultiUserChat by using the interception
facilities of the XMPPConnection.
Add ToFilter.
both serve the same purpose: As callback for Packets. There is no need
to have both, so remace PacketInterceptor and let PacketListener take
its place. Some classes like ChatStateManager can now use
MessageListener as interceptor callback, which is more convenient.
instead of using a PacketListener, which means that the user has to
downcast the Packet to Message, we now use a Listener which callback
parameter is already Message/Presence.
It is necessary to introduce MessageListener and PresenceListener, which
are interfaces that have a callback for Message/Presence instead of
Packet. The 'old' MessageListener is renamed to ChatMessageListener.
Use Generics in ConnectionDetachedPacketCollector.
- Make MultipleAddress.Type a enum
- Change the signature of the methods to use Collection instead of List
- Use for-each loops instead of iterators
- Switch Provider to new provider pattern (using switch-case)
- Use XmlStringBuilder (extend the API by two new methods)
Allows interceptor to remove themselves in the interceptPacket() method.
Same change for Interceptors as was done in
15d59299a2 for (send|recv)Listeners.
instead of rely on ListenerWrapper checking the PacketFilter *and*
invoking the PacketListener we now use two for-each loops, where the
first filters the PacketListeners that should get invoked and use the
second for-each loop to actually invoke the PacketListener.
Before, the code was not thread safe if a PacketListener would remove
itself from the (send|recv)Listeners.
Also make packet(Listener|Filter) in ListenerWrapper final.
this is the first stop towards fixing "SMACK-65: parsing should look for
depth", by providing the initial parsing depth to the provider. Some
methods (.e.g parseMessage) now use the depth as abort condition,
instead of a unclean String equals check.
parseIQ() and parseExtension() where both renamed to parse.
This also restricts the Exceptions thrown by the parse method, to just
XmlPullParserException, IOException and SmackException (not really a big
victory, but nevertheless a slight improvement).
StreamFeatureProvider is now gone, we simply use PacketExtensionProvider
for stream features.
- De-duplicate code by moving it into AbstractXMPPConnection
- Introduce TopLevelStreamElement as superclass for all XMPP stream elements.
- Add SynchronizationPoint, ParserUtils
- Add ParserUtils
Fixes SMACK-333 and SMACK-521
The minimal condition in order to check equality in XmlStringBuilder is
that 'other' implements the CharSequence interface. Not as it was
previously, that it's also a XmlStringBuilder.
This allows junit's assertEquals() to be used (to a certain extend).
Setting `jid` to `null` was probably not the intended behaviour of this constructor and means that the `IQReplyFilter` will later reject responses that it shouldn't, because the `AbstractXmppConnection` will automatically construct a JID based on the authenticated username.
In particular, this breaks attempting to connect to the PVP.net XMPP server.
inverse boolean condition, correct is: "if packetListener has been
removed, then we received no response" and add check for
exceptionCallback being null.
also remove faulty PongFilter from PingManager. It never matched any
stanzas, since a Pong is just a plain result IQ that is not qualified by
any XMPP Ping namespace.
Fixes SMACK-597
You can set your custom debugger class as before, by using clear api
method ReflectionDebuggerFactory.setDebuggerClass, or you can set custom
debugger factory using SmackConfiguration.setDebuggerFactory if it's not
enough flexible for your needs
This will help to get rid of repetitive class casts, and make
PacketCollector api more inline with itself (since some methods
are already generic return methods).
every SASL Mechanism is designed as a byte array based protocol. XMPP
adds the constraint that the challenges and responses are send base64
encoded. It's therefore better API design to let getAuthenticationText()
return byte[] instead of String.
This is a follow up on 6caf2cbdb5 where IQReplyFilter was changed so
that getUser() must not return null. But this is the case in
AccountManager where no resource binding has taken place and the user is
therefore not set.
The fix is the same as in 6caf2cbdb5, instead of IQReplyFilter we
simply use a PacketIDFilter.
as the local username is only available after binding (and legacy
session establishment). This makes Smack compatible again with XMPP
services that use the user's JID as from attribute in the result IQ
after the bind set IQ, e.g. Facebook:
SENT:
<iq id='sqvTK-1' type='set'>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
<resource>Smack</resource>
</bind>
</iq>
RCV:
<iq from='user.name.1@chat.facebook.com' id='sqvTK-1' type='result'>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
<jid>user.name.1@chat.facebook.com/Smack</jid>
</bind>
</iq>
Fixes SMACK-590
This commit marks an important milestone with the addition of the
smack-android subproject. Smack is now able to run native on Android
without requiring any modifications, which makes the aSmack build
environment obsolete.
It was necessary to redesign the code for SASL authentication to achieve
this. Smack now comes with smack-sasl-provided for SASL implementations
that do not rely on additional APIs like javax for platforms where those
APIs are not available like Android.
Adopt to common design patterns in Smack:
- getFrom(Packet) in Packetextensions
- INSTANCES.put() in getInstanceFor()
- ELEMENT instead of ELEMENT_NAME
- Use XmlStringBuilder
Removes a ton of duplicate code, mostly related to MUCItem being
duplicated in MUCOwner and MUCAdmin, but also some other duplicate code.
Make MUC code use XmlStringBuilder.
Add ELEMENT and NAMESPACE constants to the appropriate places. Also add
"static <MUCPacketExtension> getFrom(Packet)" methods.
Make some MUC classes implement Element.
Re-work filetransfer/bytestream stanza toXML() method to use
XmlStringBuilder. Move the ELEMENT and NAMESPACE definitions in the
right place, ie. the stanza class.
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.
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.
The idea that we abstract the scheduling of tasks on Android over this
method turned out to be unnecessary. schedule() was also not really part
of the *public* XMPPConnection API, so it's good that it's gone.
Move some duplicate code from XMPP(TCP|BOSH)Connection to
PacketParserUtils. Remove TestUtils as the method now part of Smack's
public API in PacketParserUtils.
This method was never intended to be part of the public API. It's also
critical that the given Runnables complete within a reasonable
time frame so that they don't block following ones.
If the connection has been reconnected, then we will receive entries
that have been unchanged since the last time we received a roster
result. Without this change, those entries ended up in 'toDelete' and
got deleted.
This change also inlines some roster methods.
Because of OSGi, no subproject of Smack (which is the same as a OSGi
bundle) must export a package that is already exported by another
subproject.
Therefore it was necessary to move the TCP and BOSH code into their own
packages: org.jivesoftware.smack.(tcp|bosh).
OSGi classloader restrictions also made it necessary to create a
Declarative Service for smack-extensions, smack-experimental and
smack-lagacy (i.e. smack subprojects which should be initialized), in
order to initialize them accordingly, as smack-core is, when used in a
OSGi environment, unable to load and initialize classes from other smack
bundles. OSGi's "Service Component Runtime" (SCR) will now take care of
running the initialization code of the particular Smack bundle by
activating its Declarative Service.
That is also the reason why most initialization related method now have an
additional classloader argument.
Note that due the refactoring, some ugly changes in XMPPTCPConnection
and its PacketReader and PacketWriter where necessary.
No code changes. Proofread API docs for Presence.java
Fixed grammar / unclear sentences in some javadocs.
Changed some nouns to be more consistent with API terminology.
Fixed some typos.
as there exists no longer a dependency from smack (now smack-core) to
smackx (now mostly smack-extensions). Therefore this approach is no
longer needed.
SMACK-343
by using a custom ArrayBlockingQueueWithShutdown. Fixes a race condition
where nextpacket() would wait for a notification that would never
arrive, because all all put(Packet) calls are still blocking.
SMACK-560
Right after PacketReader receives the 'success' stanza, indicating
successful SASL authentication, it opens a new stream. The login
process continues in another thread and checks for bindingRequired,
which may not have been set a this point yet.
bindResourceAndEstablishSession() now waits until either the binding
feature stanza is parsed or the default packet timeout occurs.
If an roster push with a roster entry without any group is processed,
then the entry is not updated, because unfiledEntries.contains(entry)
would return true, as the RosterEntry.equals() method only compares the
name.
We simply fix it by always removing the entry first and then adding it
again.
Thanks to Christian Schudt for pointing this out.
SMACK-559
Removed some throw declarations from methods, so some try/catch blocks
could be removed.
Use switch/case instead of if/else if.
Make members final when possible.
Add logger statements in case of error IQ result and remove superfluous
check of instanceof IQ.
instead of using the old baseName=smack appendix=project.name approach,
we are now going convention over configuration and renaming the
subprojects directories to the proper name.
Having a prefix is actually very helpful, because the resulting
libraries will be named like the subproject. And a core-4.0.0-rc1.jar is
not as explicit about what it actually *is* as a
smack-core-4.0.0-rc1.jar.
SMACK-265