Browse Source

Replace XPP3 by XmlPullParser interface wrapping StAX and XPP3

Introducing Smack's own XmlPullParser interface which tries to stay as
compatible as possible to XPP3. The interface is used to either wrap
StAX's XMLStreamReader if Smack is used on Java SE, and XPP3's
XmlPullParser if Smack is used on on Android.

Fixes SMACK-591.

Also introduce JUnit 5 and non-strict javadoc projects.
omemo_media_sharing
Florian Schmaus 1 year ago
parent
commit
4133eb175c
414 changed files with 3855 additions and 2041 deletions
  1. +56
    -1
      build.gradle
  2. +6
    -3
      documentation/developer/provider.md
  3. +15
    -12
      documentation/providers.md
  4. +4
    -8
      resources/releasedocs/README.html
  5. +4
    -1
      settings.gradle
  6. +1
    -0
      smack-android/build.gradle
  7. +9
    -10
      smack-bosh/src/main/java/org/jivesoftware/smack/bosh/XMPPBOSHConnection.java
  8. +4
    -8
      smack-core/build.gradle
  9. +3
    -3
      smack-core/src/integration-test/java/org/jivesoftware/smack/packet/PrivacyProviderTest.java
  10. +5
    -5
      smack-core/src/integration-test/java/org/jivesoftware/smack/test/SmackTestCase.java
  11. +3
    -3
      smack-core/src/integration-test/java/org/jivesoftware/smack/util/XMPPErrorTest.java
  12. +5
    -5
      smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java
  13. +2
    -0
      smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java
  14. +9
    -13
      smack-core/src/main/java/org/jivesoftware/smack/SmackInitialization.java
  15. +1
    -1
      smack-core/src/main/java/org/jivesoftware/smack/compress/provider/CompressedProvider.java
  16. +6
    -5
      smack-core/src/main/java/org/jivesoftware/smack/compress/provider/FailureProvider.java
  17. +6
    -5
      smack-core/src/main/java/org/jivesoftware/smack/fsm/AbstractXmppStateMachineConnection.java
  18. +1
    -1
      smack-core/src/main/java/org/jivesoftware/smack/packet/XmlEnvironment.java
  19. +11
    -8
      smack-core/src/main/java/org/jivesoftware/smack/parsing/StandardExtensionElementProvider.java
  20. +8
    -5
      smack-core/src/main/java/org/jivesoftware/smack/provider/BindIQProvider.java
  21. +2
    -2
      smack-core/src/main/java/org/jivesoftware/smack/provider/BodyElementProvider.java
  22. +5
    -5
      smack-core/src/main/java/org/jivesoftware/smack/provider/EmbeddedExtensionProvider.java
  23. +8
    -5
      smack-core/src/main/java/org/jivesoftware/smack/provider/IntrospectionProvider.java
  24. +2
    -2
      smack-core/src/main/java/org/jivesoftware/smack/provider/Provider.java
  25. +6
    -9
      smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderFileLoader.java
  26. +1
    -1
      smack-core/src/main/java/org/jivesoftware/smack/provider/TlsFailureProvider.java
  27. +1
    -1
      smack-core/src/main/java/org/jivesoftware/smack/provider/TlsProceedProvider.java
  28. +164
    -233
      smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java
  29. +6
    -6
      smack-core/src/main/java/org/jivesoftware/smack/util/ParserUtils.java
  30. +2
    -2
      smack-core/src/test/java/org/jivesoftware/smack/compress/provider/FailureProviderTest.java
  31. +39
    -39
      smack-core/src/test/java/org/jivesoftware/smack/packet/StreamErrorTest.java
  32. +3
    -3
      smack-core/src/test/java/org/jivesoftware/smack/parsing/ParsingExceptionTest.java
  33. +1
    -1
      smack-core/src/test/java/org/jivesoftware/smack/provider/ProviderConfigTest.java
  34. +1
    -1
      smack-core/src/test/java/org/jivesoftware/smack/provider/ProviderManagerTest.java
  35. +3
    -3
      smack-core/src/test/java/org/jivesoftware/smack/sasl/DigestMd5SaslTest.java
  36. +165
    -0
      smack-core/src/test/java/org/jivesoftware/smack/test/util/SmackTestUtil.java
  37. +8
    -24
      smack-core/src/test/java/org/jivesoftware/smack/test/util/TestUtils.java
  38. +36
    -22
      smack-core/src/test/java/org/jivesoftware/smack/util/PacketParserUtilsTest.java
  39. +231
    -0
      smack-core/src/test/java/org/jivesoftware/smack/xml/XmlPullParserTest.java
  40. +5
    -6
      smack-experimental/src/main/java/org/jivesoftware/smackx/carbons/provider/CarbonManagerProvider.java
  41. +1
    -0
      smack-experimental/src/main/java/org/jivesoftware/smackx/chat_markers/ChatMarkersManager.java
  42. +1
    -0
      smack-experimental/src/main/java/org/jivesoftware/smackx/chat_markers/element/ChatMarkersElements.java
  43. +1
    -0
      smack-experimental/src/main/java/org/jivesoftware/smackx/chat_markers/filter/ChatMarkersFilter.java
  44. +1
    -0
      smack-experimental/src/main/java/org/jivesoftware/smackx/chat_markers/filter/EligibleForChatMarkerFilter.java
  45. +1
    -2
      smack-experimental/src/main/java/org/jivesoftware/smackx/chat_markers/provider/AcknowledgedProvider.java
  46. +1
    -2
      smack-experimental/src/main/java/org/jivesoftware/smackx/chat_markers/provider/DisplayedProvider.java
  47. +1
    -2
      smack-experimental/src/main/java/org/jivesoftware/smackx/chat_markers/provider/MarkableProvider.java
  48. +1
    -2
      smack-experimental/src/main/java/org/jivesoftware/smackx/chat_markers/provider/ReceivedProvider.java
  49. +2
    -3
      smack-experimental/src/main/java/org/jivesoftware/smackx/csi/provider/ClientStateIndicationFeatureProvider.java
  50. +1
    -0
      smack-experimental/src/main/java/org/jivesoftware/smackx/dox/DnsOverXmppManager.java
  51. +3
    -3
      smack-experimental/src/main/java/org/jivesoftware/smackx/dox/provider/DnsIqProvider.java
  52. +1
    -2
      smack-experimental/src/main/java/org/jivesoftware/smackx/eme/provider/ExplicitMessageEncryptionProvider.java
  53. +5
    -4
      smack-experimental/src/main/java/org/jivesoftware/smackx/hashes/provider/HashElementProvider.java
  54. +1
    -2
      smack-experimental/src/main/java/org/jivesoftware/smackx/hints/provider/MessageProcessingHintProvider.java
  55. +22
    -23
      smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/provider/AbstractHttpOverXmppProvider.java
  56. +5
    -6
      smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/provider/Base64BinaryChunkProvider.java
  57. +2
    -3
      smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/provider/HttpOverXmppReqProvider.java
  58. +3
    -3
      smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/provider/HttpOverXmppRespProvider.java
  59. +8
    -6
      smack-experimental/src/main/java/org/jivesoftware/smackx/httpfileupload/provider/FileTooLargeErrorProvider.java
  60. +14
    -9
      smack-experimental/src/main/java/org/jivesoftware/smackx/httpfileupload/provider/SlotProvider.java
  61. +8
    -6
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/provider/IoTSetRequestProvider.java
  62. +1
    -2
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/provider/IoTSetResponseProvider.java
  63. +1
    -2
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/provider/IoTDataReadOutAcceptedProvider.java
  64. +1
    -2
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/provider/IoTDataRequestProvider.java
  65. +20
    -11
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/provider/IoTFieldsExtensionProvider.java
  66. +1
    -1
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/provider/IoTClaimedProvider.java
  67. +1
    -1
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/provider/IoTDisownProvider.java
  68. +1
    -2
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/provider/IoTDisownedProvider.java
  69. +4
    -5
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/provider/IoTRegisterProvider.java
  70. +1
    -1
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/provider/IoTRemoveProvider.java
  71. +1
    -2
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/provider/IoTRemovedProvider.java
  72. +1
    -2
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/provider/IoTUnregisterProvider.java
  73. +2
    -2
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/parser/NodeInfoParser.java
  74. +1
    -2
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/provider/ClearCacheProvider.java
  75. +1
    -2
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/provider/ClearCacheResponseProvider.java
  76. +1
    -1
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/provider/FriendProvider.java
  77. +1
    -1
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/provider/IoTIsFriendProvider.java
  78. +1
    -1
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/provider/IoTIsFriendResponseProvider.java
  79. +1
    -1
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/provider/UnfriendProvider.java
  80. +1
    -0
      smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/Checksum.java
  81. +1
    -0
      smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/JingleFileTransferChild.java
  82. +9
    -7
      smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/element/Range.java
  83. +9
    -9
      smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/provider/ChecksumProvider.java
  84. +55
    -39
      smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/provider/JingleFileTransferProvider.java
  85. +2
    -3
      smack-experimental/src/main/java/org/jivesoftware/smackx/json/provider/AbstractJsonExtensionProvider.java
  86. +8
    -6
      smack-experimental/src/main/java/org/jivesoftware/smackx/mam/provider/MamFinIQProvider.java
  87. +14
    -8
      smack-experimental/src/main/java/org/jivesoftware/smackx/mam/provider/MamPrefsIQProvider.java
  88. +8
    -6
      smack-experimental/src/main/java/org/jivesoftware/smackx/mam/provider/MamQueryIQProvider.java
  89. +8
    -6
      smack-experimental/src/main/java/org/jivesoftware/smackx/mam/provider/MamResultProvider.java
  90. +10
    -9
      smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/provider/MarkupElementProvider.java
  91. +5
    -5
      smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/provider/MUCLightAffiliationsChangeProvider.java
  92. +5
    -5
      smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/provider/MUCLightAffiliationsIQProvider.java
  93. +5
    -5
      smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/provider/MUCLightBlockingIQProvider.java
  94. +5
    -6
      smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/provider/MUCLightConfigurationIQProvider.java
  95. +5
    -6
      smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/provider/MUCLightConfigurationsChangeProvider.java
  96. +10
    -10
      smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/provider/MUCLightInfoIQProvider.java
  97. +5
    -5
      smack-experimental/src/main/java/org/jivesoftware/smackx/push_notifications/provider/RemoteDisablingProvider.java
  98. +1
    -0
      smack-experimental/src/main/java/org/jivesoftware/smackx/reference/ReferenceManager.java
  99. +1
    -0
      smack-experimental/src/main/java/org/jivesoftware/smackx/reference/element/ReferenceElement.java
  100. +6
    -6
      smack-experimental/src/main/java/org/jivesoftware/smackx/reference/provider/ReferenceProvider.java

+ 56
- 1
build.gradle View File

@ -24,6 +24,7 @@ apply from: 'version.gradle'
allprojects {
apply plugin: 'java'
apply plugin: 'java-library'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'jacoco'
@ -80,6 +81,8 @@ allprojects {
':smack-omemo',
':smack-omemo-signal',
':smack-openpgp',
':smack-xmlparser',
':smack-xmlparser-xpp3',
].collect{ project(it) }
androidBootClasspathProjects = [
':smack-android',
@ -97,13 +100,37 @@ allprojects {
':smack-omemo-signal',
':smack-omemo-signal-integration-test',
].collect{ project(it) }
// When this list is empty, then move the according javadoc
// tool Werror option into the global configure section.
nonStrictJavadocProjects = [
':smack-bosh',
':smack-core',
':smack-experimental',
':smack-extensions',
':smack-im',
':smack-integration-test',
':smack-jingle-old',
':smack-legacy',
':smack-omemo',
':smack-tcp',
].collect{ project(it) }
// Lazily evaluate the Android bootClasspath and offline
// Javadoc using a closure, so that targets which do not
// require it are still able to succeed without an Android
// SDK.
androidBootClasspath = { getAndroidRuntimeJar() }
androidJavadocOffline = { getAndroidJavadocOffline() }
junitVersion = '5.2.0'
junit4Projects = [
':smack-core',
':smack-extensions',
':smack-im',
':smack-integration-test',
':smack-omemo',
':smack-omemo-signal',
':smack-openpgp',
].collect { project(it) }
junitVersion = '5.4.2'
powerMockVersion = '1.7.3'
}
group = 'org.igniterealtime.smack'
sourceCompatibility = JavaVersion.VERSION_1_8
@ -114,6 +141,12 @@ allprojects {
}
test {
useJUnitPlatform()
// Enable once the tests are fixed that sometimes break if
// they are executed in parallel (.e.g Socks5)
// maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
// Enable full stacktraces of failed tests. Especially handy
// for environments like Travis.
testLogging {
@ -232,6 +265,10 @@ allprojects {
}
dependencies {
testImplementation "org.junit.jupiter:junit-jupiter-api:$junitVersion"
testImplementation "org.junit.jupiter:junit-jupiter-params:$junitVersion"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junitVersion"
errorprone 'com.google.errorprone:error_prone_core:2.3.2'
errorproneJavac('com.google.errorprone:javac:9+181-r4173-1')
}
@ -241,6 +278,15 @@ allprojects {
test { dependsOn javadoc }
}
configure (junit4Projects) {
dependencies {
testImplementation "org.junit.vintage:junit-vintage-engine:$junitVersion"
testImplementation "org.powermock:powermock-module-junit4:$powerMockVersion"
testImplementation "org.powermock:powermock-module-junit4-rule:$powerMockVersion"
testImplementation "org.powermock:powermock-api-mockito2:$powerMockVersion"
}
}
gradle.taskGraph.whenReady { taskGraph ->
if (signingRequired
&& taskGraph.allTasks.any { it instanceof Sign }) {
@ -532,6 +578,15 @@ subprojects*.jar {
}
}
configure(subprojects - nonStrictJavadocProjects) {
tasks.withType(Javadoc) {
// Abort on javadoc warnings.
// See JDK-8200363 (https://bugs.openjdk.java.net/browse/JDK-8200363)
// for information about the -Xwerror option.
options.addStringOption('Xwerror', '-quiet')
}
}
configure(subprojects - gplLicensedProjects) {
checkstyle {
configProperties.checkstyleLicenseHeader = "header"

+ 6
- 3
documentation/developer/provider.md View File

@ -27,11 +27,11 @@ public MyExtension parse(XmlPullParser parser, int initialDepth) {
outerloop: while(true) {
// Make sure to have already parse all attributes of the outermost element,
// i.e. 'attrFoo' of 'myExtension' in this example. Then advance the parser
int event = parser.next();
XmlPullParser.Event event = parser.next();
// Use switch/case of int instead of a if/else-if cascade
switch (event) {
case XmlPullParser.START_TAG:
case START_ELEMENT:
// Determine the name of the element which start tag we are seeing
String name = parser.getName();
// We can use switch/case of Strings since Java7, make use of its advantages
@ -52,12 +52,15 @@ public MyExtension parse(XmlPullParser parser, int initialDepth) {
break;
}
break;
case XmlPullParser.END_TAG:
case END_ELEMENT:
// The abort condition with the break labeled loop statement
if (parser.getDepth() == initialDepth) {
break outerloop;
}
break;
default:
// Catch all for incomplete switch (MissingCasesInEnumSwitch) statement.
break;
}
}

+ 15
- 12
documentation/providers.md View File

@ -23,7 +23,7 @@ Whenever a packet extension is found in a packet, parsing will be
passed to the correct provider. Each provider must extend the
ExtensionElementProvider abstract class. Each extension provider is
responsible for parsing the raw XML stream, via the
[XML Pull Parser](http://www.xmlpull.org/), to contruct an object.
Smack's `XmlPullParser` interface, to construct an object.
You can also create an introspection provider
(`provider.IntrospectionProvider.PacketExtensionIntrospectionProvider`). Here,
@ -161,9 +161,9 @@ public class MyIQProvider extends IQProvider {
// Start parsing loop
outerloop: while(true) {
int eventType = parser.next();
XmlPullParser.Event eventType = parser.next();
switch(eventType) {
case XmlPullParser.START_TAG:
case START_ELEMENT:
String elementName = parser.getName();
switch (elementName) {
case "user":
@ -175,12 +175,15 @@ public class MyIQProvider extends IQProvider {
break;
}
break;
case XmlPullParser.END_TAG:
case END_ELEMENT:
// Abort condition: if the are on a end tag (closing element) of the same depth
if (parser.getDepth() == initialDepth) {
break outerloop;
}
break;
default:
// Catch all for incomplete switch (MissingCasesInEnumSwitch) statement.
break;
}
}
@ -225,9 +228,9 @@ _Disco Items IQProvider_
String node = "";
discoverItems.setNode(parser.getAttributeValue("", "node"));
outerloop: while (true) {
int eventType = parser.next();
XmlPullParser.Event eventType = parser.next();
switch (eventType) {
case XmlPullParser.START_TAG:
case START_ELEMENT:
String elementName = parser.getName();
switch (elementName) {
case "item":
@ -239,7 +242,7 @@ _Disco Items IQProvider_
break;
}
break;
case XmlPullParser.END_TAG:
case END_ELEMENT:
String elementName = parser.getName();
switch (elementName) {
case "item":
@ -295,17 +298,17 @@ _Subscription PacketExtensionProvider Implementation_
String state = parser.getAttributeValue(null, "subscription");
boolean isRequired = false;
int tag = parser.next();
XmlPullParser.Event tag = parser.next();
if ((tag == XmlPullParser.START_TAG) && parser.getName().equals("subscribe-options")) {
if ((tag == XmlPullParser.START_ELEMENT) && parser.getName().equals("subscribe-options")) {
tag = parser.next();
if ((tag == XmlPullParser.START_TAG) && parser.getName().equals("required"))
if ((tag == XmlPullParser.START_ELEMENT) && parser.getName().equals("required"))
isRequired = true;
while (parser.next() != XmlPullParser.END_TAG && parser.getName() != "subscribe-options");
while (parser.next() != XmlPullParser.END_ELEMENT && parser.getName() != "subscribe-options");
}
while (parser.getEventType() != XmlPullParser.END_TAG) parser.next();
while (parser.getEventType() != XmlPullParser.END_ELEMENT) parser.next();
return new Subscription(jid, nodeId, subId, state == null ? null : Subscription.State.valueOf(state), isRequired);
}
}

+ 4
- 8
resources/releasedocs/README.html View File

@ -169,14 +169,10 @@ recommended when using Smack.
</p>
<p>
If you dont' use a
dependency resolution system, like gradle or maven, then you will need
to download at least
the <a href="http://www.extreme.indiana.edu/xgws/xsoap/xpp/mxp1/">Xml
Pull Parser 3rd Edition (XPP3) library</a> or any other library that
implements the XmlPullParser interface
(like <a href="http://kxml.org/">kXML</a>) and the set of
<a href="http://jxmpp.org">jXMPP libraries</a>.
Smack tries to depend on as few as possible libraries. The only
requirement is <a href="http://jxmpp.org">jXMPP</a>. For DNS
resolution we recommend to
use <a href="http://minidns.org">MiniDNS</a>.
</p>
<p>

+ 4
- 1
settings.gradle View File

@ -28,4 +28,7 @@ include 'smack-core',
'smack-omemo-signal',
'smack-omemo-signal-integration-test',
'smack-repl',
'smack-openpgp'
'smack-openpgp',
'smack-xmlparser',
'smack-xmlparser-stax',
'smack-xmlparser-xpp3'

+ 1
- 0
smack-android/build.gradle View File

@ -7,6 +7,7 @@ smack-extensions and smack-experimental."""
// Note that the test dependencies (junit, ) are inferred from the
// sourceSet.test of the core subproject
dependencies {
api project(':smack-xmlparser-xpp3')
// Depend on minidns-android21 as optional dependency, even if may
// not need it. Can't hurt to have it in the programm path with
// the correct MiniDNS version as it won't hurt even if the

+ 9
- 10
smack-bosh/src/main/java/org/jivesoftware/smack/bosh/XMPPBOSHConnection.java View File

@ -20,7 +20,6 @@ package org.jivesoftware.smack.bosh;
import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter;
import java.io.StringReader;
import java.io.Writer;
import java.util.Map;
import java.util.logging.Level;
@ -44,6 +43,7 @@ import org.jivesoftware.smack.sasl.packet.SaslStreamElements.SASLFailure;
import org.jivesoftware.smack.sasl.packet.SaslStreamElements.Success;
import org.jivesoftware.smack.util.CloseableUtil;
import org.jivesoftware.smack.util.PacketParserUtils;
import org.jivesoftware.smack.xml.XmlPullParser;
import org.igniterealtime.jbosh.AbstractBody;
import org.igniterealtime.jbosh.BOSHClient;
@ -56,11 +56,8 @@ import org.igniterealtime.jbosh.BOSHException;
import org.igniterealtime.jbosh.BOSHMessageEvent;
import org.igniterealtime.jbosh.BodyQName;
import org.igniterealtime.jbosh.ComposableBody;
import org.jxmpp.jid.DomainBareJid;
import org.jxmpp.jid.parts.Resourcepart;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
/**
* Creates a connection to an XMPP server via HTTP binding.
@ -479,14 +476,13 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
if (streamId == null) {
streamId = body.getAttribute(BodyQName.create(XMPPBOSHConnection.BOSH_URI, "authid"));
}
final XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
parser.setInput(new StringReader(body.toXML()));
int eventType = parser.getEventType();
final XmlPullParser parser = PacketParserUtils.getParserFor(body.toXML());
XmlPullParser.Event eventType = parser.getEventType();
do {
eventType = parser.next();
switch (eventType) {
case XmlPullParser.START_TAG:
case START_ELEMENT:
String name = parser.getName();
switch (name) {
case Message.ELEMENT:
@ -528,9 +524,12 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
}
}
break;
default:
// Catch all for incomplete switch (MissingCasesInEnumSwitch) statement.
break;
}
}
while (eventType != XmlPullParser.END_DOCUMENT);
while (eventType != XmlPullParser.Event.END_DOCUMENT);
}
catch (Exception e) {
if (isConnected()) {

+ 4
- 8
smack-core/build.gradle View File

@ -2,23 +2,19 @@ description = """\
Smack core components."""
ext {
xmlUnitVersion = "2.6.0"
powerMockVersion = "1.7.3"
xmlUnitVersion = '2.6.2'
}
dependencies {
compile 'xpp3:xpp3:1.1.4c'
compile project(':smack-xmlparser')
compile "org.jxmpp:jxmpp-core:$jxmppVersion"
compile "org.jxmpp:jxmpp-jid:$jxmppVersion"
compile "org.minidns:minidns-core:$miniDnsVersion"
testCompile project(':smack-xmlparser-stax')
testCompile project(':smack-xmlparser-xpp3')
testCompile "org.jxmpp:jxmpp-jid:$jxmppVersion:tests"
testCompile "org.junit.jupiter:junit-jupiter-api:$junitVersion"
testCompile "org.junit.vintage:junit-vintage-engine:$junitVersion"
testCompile "org.xmlunit:xmlunit-core:$xmlUnitVersion"
testCompile "org.xmlunit:xmlunit-legacy:$xmlUnitVersion"
testCompile "org.powermock:powermock-module-junit4:$powerMockVersion"
testCompile "org.powermock:powermock-module-junit4-rule:$powerMockVersion"
testCompile "org.powermock:powermock-api-mockito2:$powerMockVersion"
testCompile 'com.jamesmurty.utils:java-xmlbuilder:1.2'
}

+ 3
- 3
smack-core/src/integration-test/java/org/jivesoftware/smack/packet/PrivacyProviderTest.java View File

@ -16,9 +16,9 @@ package org.jivesoftware.smack.packet;
import org.jivesoftware.smack.provider.PrivacyProvider;
import org.jivesoftware.smack.test.SmackTestCase;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.jivesoftware.smack.xml.XmlPullParserFactory;
import org.jivesoftware.smack.xml.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParserException;
import java.io.StringReader;

+ 5
- 5
smack-core/src/integration-test/java/org/jivesoftware/smack/test/SmackTestCase.java View File

@ -32,8 +32,8 @@ import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.TCPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.util.ConnectionUtils;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParserFactory;
import org.jivesoftware.smack.xml.XmlPullParser;
/**
* Base class for all the test cases which provides a pre-configured execution context. This
@ -414,9 +414,9 @@ public abstract class SmackTestCase extends TestCase {
XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
parser.setInput(systemStream, "UTF-8");
int eventType = parser.getEventType();
XmlPullParser.Event eventType = parser.getEventType();
do {
if (eventType == XmlPullParser.START_TAG) {
if (eventType == START_ELEMENT) {
if (parser.getName().equals("host")) {
host = parser.nextText();
}
@ -459,7 +459,7 @@ public abstract class SmackTestCase extends TestCase {
}
eventType = parser.next();
}
while (eventType != XmlPullParser.END_DOCUMENT);
while (eventType != END_DOCUMENT);
parsedOK = true;
}
catch (Exception e) {

+ 3
- 3
smack-core/src/integration-test/java/org/jivesoftware/smack/util/XMPPErrorTest.java View File

@ -20,9 +20,9 @@ import java.io.StringReader;
import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.test.SmackTestCase;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.jivesoftware.smack.xml.XmlPullParserFactory;
import org.jivesoftware.smack.xml.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParserException;
public class XMPPErrorTest extends SmackTestCase {

+ 5
- 5
smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java View File

@ -121,6 +121,8 @@ import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.util.dns.HostAddress;
import org.jivesoftware.smack.util.dns.SmackDaneProvider;
import org.jivesoftware.smack.util.dns.SmackDaneVerifier;
import org.jivesoftware.smack.xml.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParserException;
import org.jxmpp.jid.DomainBareJid;
import org.jxmpp.jid.EntityFullJid;
@ -130,8 +132,6 @@ import org.jxmpp.jid.parts.Resourcepart;
import org.jxmpp.stringprep.XmppStringprepException;
import org.jxmpp.util.XmppStringUtils;
import org.minidns.dnsname.DnsName;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
/**
@ -1614,9 +1614,9 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
streamFeatures.clear();
final int initialDepth = parser.getDepth();
while (true) {
int eventType = parser.next();
XmlPullParser.Event eventType = parser.next();
if (eventType == XmlPullParser.START_TAG && parser.getDepth() == initialDepth + 1) {
if (eventType == XmlPullParser.Event.START_ELEMENT && parser.getDepth() == initialDepth + 1) {
FullyQualifiedElement streamFeature = null;
String name = parser.getName();
String namespace = parser.getNamespace();
@ -1647,7 +1647,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
addStreamFeature(streamFeature);
}
}
else if (eventType == XmlPullParser.END_TAG && parser.getDepth() == initialDepth) {
else if (eventType == XmlPullParser.Event.END_ELEMENT && parser.getDepth() == initialDepth) {
break;
}
}

+ 2
- 0
smack-core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java View File

@ -29,6 +29,7 @@ import javax.net.ssl.HostnameVerifier;
import org.jivesoftware.smack.compression.XMPPInputOutputStream;
import org.jivesoftware.smack.debugger.ReflectionDebuggerFactory;
import org.jivesoftware.smack.debugger.SmackDebuggerFactory;
import org.jivesoftware.smack.parsing.ExceptionThrowingCallback;
import org.jivesoftware.smack.parsing.ExceptionThrowingCallbackWithHint;
import org.jivesoftware.smack.parsing.ParsingExceptionCallback;
import org.jivesoftware.smack.util.Objects;
@ -380,4 +381,5 @@ public final class SmackConfiguration {
public static int getDefaultConcurrencyLevelLimit() {
return defaultConcurrencyLevelLimit;
}
}

+ 9
- 13
smack-core/src/main/java/org/jivesoftware/smack/SmackInitialization.java View File

@ -44,10 +44,10 @@ import org.jivesoftware.smack.sasl.core.SCRAMSHA1Mechanism;
import org.jivesoftware.smack.sasl.core.ScramSha1PlusMechanism;
import org.jivesoftware.smack.util.CloseableUtil;
import org.jivesoftware.smack.util.FileUtils;
import org.jivesoftware.smack.util.PacketParserUtils;
import org.jivesoftware.smack.util.StringUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import org.jivesoftware.smack.xml.XmlPullParser;
public final class SmackInitialization {
@ -141,12 +141,10 @@ public final class SmackInitialization {
public static void processConfigFile(InputStream cfgFileStream,
Collection<Exception> exceptions, ClassLoader classLoader) throws Exception {
XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
parser.setInput(cfgFileStream, "UTF-8");
int eventType = parser.getEventType();
XmlPullParser parser = PacketParserUtils.getParserFor(cfgFileStream);
XmlPullParser.Event eventType = parser.getEventType();
do {
if (eventType == XmlPullParser.START_TAG) {
if (eventType == XmlPullParser.Event.START_ELEMENT) {
if (parser.getName().equals("startupClasses")) {
parseClassesToLoad(parser, false, exceptions, classLoader);
}
@ -156,7 +154,7 @@ public final class SmackInitialization {
}
eventType = parser.next();
}
while (eventType != XmlPullParser.END_DOCUMENT);
while (eventType != XmlPullParser.Event.END_DOCUMENT);
CloseableUtil.maybeClose(cfgFileStream, LOGGER);
}
@ -164,12 +162,10 @@ public final class SmackInitialization {
Collection<Exception> exceptions, ClassLoader classLoader)
throws Exception {
final String startName = parser.getName();
int eventType;
String name;
XmlPullParser.Event eventType;
outerloop: do {
eventType = parser.next();
name = parser.getName();
if (eventType == XmlPullParser.START_TAG && "className".equals(name)) {
if (eventType == XmlPullParser.Event.START_ELEMENT && "className".equals(parser.getName())) {
String classToLoad = parser.nextText();
if (SmackConfiguration.isDisabledSmackClass(classToLoad)) {
continue outerloop;
@ -188,7 +184,7 @@ public final class SmackInitialization {
}
}
}
while (!(eventType == XmlPullParser.END_TAG && startName.equals(name)));
while (!(eventType == XmlPullParser.Event.END_ELEMENT && startName.equals(parser.getName())));
}
private static void loadSmackClass(String className, boolean optional, ClassLoader classLoader) throws Exception {

+ 1
- 1
smack-core/src/main/java/org/jivesoftware/smack/compress/provider/CompressedProvider.java View File

@ -20,7 +20,7 @@ import org.jivesoftware.smack.compress.packet.Compressed;
import org.jivesoftware.smack.packet.XmlEnvironment;
import org.jivesoftware.smack.provider.NonzaProvider;
import org.xmlpull.v1.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParser;
public final class CompressedProvider extends NonzaProvider<Compressed> {

+ 6
- 5
smack-core/src/main/java/org/jivesoftware/smack/compress/provider/FailureProvider.java View File

@ -27,8 +27,8 @@ import org.jivesoftware.smack.parsing.SmackParsingException;
import org.jivesoftware.smack.provider.NonzaProvider;
import org.jivesoftware.smack.util.PacketParserUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.jivesoftware.smack.xml.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParserException;
public final class FailureProvider extends NonzaProvider<Failure> {
@ -46,9 +46,9 @@ public final class FailureProvider extends NonzaProvider {
XmlEnvironment failureXmlEnvironment = XmlEnvironment.from(parser, xmlEnvironment);
outerloop: while (true) {
int eventType = parser.next();
XmlPullParser.Event eventType = parser.next();
switch (eventType) {
case XmlPullParser.START_TAG:
case START_ELEMENT:
String name = parser.getName();
String namespace = parser.getNamespace();
switch (namespace) {
@ -72,11 +72,12 @@ public final class FailureProvider extends NonzaProvider {
break;
}
break;
case XmlPullParser.END_TAG:
case END_ELEMENT:
if (parser.getDepth() == initialDepth) {
break outerloop;
}
break;
default: // fall out
}
}

+ 6
- 5
smack-core/src/main/java/org/jivesoftware/smack/fsm/AbstractXmppStateMachineConnection.java View File

@ -57,10 +57,10 @@ import org.jivesoftware.smack.sasl.packet.SaslStreamElements.Challenge;
import org.jivesoftware.smack.sasl.packet.SaslStreamElements.Success;
import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smack.util.PacketParserUtils;
import org.jivesoftware.smack.xml.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParserException;
import org.jxmpp.jid.parts.Resourcepart;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
public abstract class AbstractXmppStateMachineConnection extends AbstractXMPPConnection {
@ -310,10 +310,10 @@ public abstract class AbstractXmppStateMachineConnection extends AbstractXMPPCon
// Skip the enclosing stream open what is guaranteed to be there.
parser.next();
int event = parser.getEventType();
XmlPullParser.Event event = parser.getEventType();
outerloop: while (true) {
switch (event) {
case XmlPullParser.START_TAG:
case START_ELEMENT:
final String name = parser.getName();
// Note that we don't handle "stream" here as it's done in the splitter.
switch (name) {
@ -353,8 +353,9 @@ public abstract class AbstractXmppStateMachineConnection extends AbstractXMPPCon
break;
}
break;
case XmlPullParser.END_DOCUMENT:
case END_DOCUMENT:
break outerloop;
default: // fall out
}
event = parser.next();
}

+ 1
- 1
smack-core/src/main/java/org/jivesoftware/smack/packet/XmlEnvironment.java View File

@ -19,7 +19,7 @@ package org.jivesoftware.smack.packet;
import org.jivesoftware.smack.util.ParserUtils;
import org.jivesoftware.smack.util.StringUtils;
import org.xmlpull.v1.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParser;
public class XmlEnvironment {

+ 11
- 8
smack-core/src/main/java/org/jivesoftware/smack/parsing/StandardExtensionElementProvider.java View File

@ -1,6 +1,6 @@
/**
*
* Copyright 2015 Florian Schmaus.
* Copyright 2015-2019 Florian Schmaus.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -26,8 +26,8 @@ import org.jivesoftware.smack.provider.ExtensionElementProvider;
import org.jivesoftware.smack.util.ParserUtils;
import org.jivesoftware.smack.util.StringUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.jivesoftware.smack.xml.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParserException;
/**
* The parser for {@link StandardExtensionElement}s.
@ -47,7 +47,7 @@ public class StandardExtensionElementProvider extends ExtensionElementProvider
String name = parser.getName();
String namespace = parser.getNamespace();
StandardExtensionElement.Builder builder = StandardExtensionElement.builder(name, namespace);
final int namespaceCount = parser.getNamespaceCount(initialDepth);
final int namespaceCount = parser.getNamespaceCount();
final int attributeCount = parser.getAttributeCount();
final Map<String, String> attributes = new LinkedHashMap<>(namespaceCount + attributeCount);
for (int i = 0; i < namespaceCount; i++) {
@ -77,19 +77,22 @@ public class StandardExtensionElementProvider extends ExtensionElementProvider
builder.addAttributes(attributes);
outerloop: while (true) {
int event = parser.next();
XmlPullParser.Event event = parser.next();
switch (event) {
case XmlPullParser.START_TAG:
case START_ELEMENT:
builder.addElement(parse(parser, parser.getDepth(), xmlEnvironment));
break;
case XmlPullParser.TEXT:
case TEXT_CHARACTERS:
builder.setText(parser.getText());
break;
case XmlPullParser.END_TAG:
case END_ELEMENT:
if (initialDepth == parser.getDepth()) {
break outerloop;
}
break;
default:
// Catch all for incomplete switch (MissingCasesInEnumSwitch) statement.
break;
}
}

+ 8
- 5
smack-core/src/main/java/org/jivesoftware/smack/provider/BindIQProvider.java View File

@ -20,12 +20,12 @@ import java.io.IOException;
import org.jivesoftware.smack.packet.Bind;
import org.jivesoftware.smack.packet.XmlEnvironment;
import org.jivesoftware.smack.xml.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParserException;
import org.jxmpp.jid.EntityFullJid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.jid.parts.Resourcepart;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
public class BindIQProvider extends IQProvider<Bind> {
@ -34,9 +34,9 @@ public class BindIQProvider extends IQProvider {
String name;
Bind bind = null;
outerloop: while (true) {
int eventType = parser.next();
XmlPullParser.Event eventType = parser.next();
switch (eventType) {
case XmlPullParser.START_TAG:
case START_ELEMENT:
name = parser.getName();
switch (name) {
case "resource":
@ -49,11 +49,14 @@ public class BindIQProvider extends IQProvider {
break;
}
break;
case XmlPullParser.END_TAG:
case END_ELEMENT:
if (parser.getDepth() == initialDepth) {
break outerloop;
}
break;
default:
// Catch all for incomplete switch (MissingCasesInEnumSwitch) statement.
break;
}
}
return bind;

+ 2
- 2
smack-core/src/main/java/org/jivesoftware/smack/provider/BodyElementProvider.java View File

@ -24,8 +24,8 @@ import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.XmlEnvironment;
import org.jivesoftware.smack.util.ParserUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.jivesoftware.smack.xml.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParserException;
public class BodyElementProvider extends ExtensionElementProvider<Message.Body> {

+ 5
- 5
smack-core/src/main/java/org/jivesoftware/smack/provider/EmbeddedExtensionProvider.java View File

@ -27,8 +27,8 @@ import org.jivesoftware.smack.packet.XmlEnvironment;
import org.jivesoftware.smack.parsing.SmackParsingException;
import org.jivesoftware.smack.util.PacketParserUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.jivesoftware.smack.xml.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParserException;
/**
*
@ -97,14 +97,14 @@ public abstract class EmbeddedExtensionProvider ext
}
List<ExtensionElement> extensions = new ArrayList<>();
int event;
XmlPullParser.Event event;
do {
event = parser.next();
if (event == XmlPullParser.START_TAG)
if (event == XmlPullParser.Event.START_ELEMENT)
PacketParserUtils.addExtensionElement(extensions, parser, xmlEnvironment);
}
while (!(event == XmlPullParser.END_TAG && parser.getDepth() == initialDepth));
while (!(event == XmlPullParser.Event.END_ELEMENT && parser.getDepth() == initialDepth));
return createReturnExtension(name, namespace, attMap, extensions);
}

+ 8
- 5
smack-core/src/main/java/org/jivesoftware/smack/provider/IntrospectionProvider.java View File

@ -24,8 +24,8 @@ import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.XmlEnvironment;
import org.jivesoftware.smack.util.ParserUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.jivesoftware.smack.xml.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParserException;
public class IntrospectionProvider{
@ -81,9 +81,9 @@ public class IntrospectionProvider{
ParserUtils.assertAtStartTag(parser);
Object object = objectClass.getConstructor().newInstance();
outerloop: while (true) {
int eventType = parser.next();
XmlPullParser.Event eventType = parser.next();
switch (eventType) {
case XmlPullParser.START_TAG:
case START_ELEMENT:
String name = parser.getName();
String stringValue = parser.nextText();
Class<?> propertyType = object.getClass().getMethod(
@ -97,11 +97,14 @@ public class IntrospectionProvider{
propertyType).invoke(object, value);
break;
case XmlPullParser.END_TAG:
case END_ELEMENT:
if (parser.getDepth() == initialDepth) {
break outerloop;
}
break;
default:
// Catch all for incomplete switch (MissingCasesInEnumSwitch) statement.
break;
}
}
ParserUtils.assertAtEndTag(parser);

+ 2
- 2
smack-core/src/main/java/org/jivesoftware/smack/provider/Provider.java View File

@ -26,8 +26,8 @@ import org.jivesoftware.smack.packet.XmlEnvironment;
import org.jivesoftware.smack.parsing.SmackParsingException;
import org.jivesoftware.smack.util.ParserUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.jivesoftware.smack.xml.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParserException;
/**
* Smack provider are the parsers used to deserialize raw XMPP into the according Java {@link Element}s.

+ 6
- 9
smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderFileLoader.java View File

@ -26,9 +26,8 @@ import java.util.logging.Logger;
import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.packet.IQ;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import org.jivesoftware.smack.util.PacketParserUtils;
import org.jivesoftware.smack.xml.XmlPullParser;
/**
* Loads the {@link IQProvider} and {@link ExtensionElementProvider} information from a standard provider file in preparation
@ -54,12 +53,10 @@ public class ProviderFileLoader implements ProviderLoader {
public ProviderFileLoader(InputStream providerStream, ClassLoader classLoader) {
// Load processing providers.
try (InputStream is = providerStream) {
XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
parser.setInput(is, "UTF-8");
int eventType = parser.getEventType();
XmlPullParser parser = PacketParserUtils.getParserFor(is);
XmlPullParser.Event eventType = parser.getEventType();
do {
if (eventType == XmlPullParser.START_TAG) {
if (eventType == XmlPullParser.Event.START_ELEMENT) {
final String typeName = parser.getName();
try {
@ -134,7 +131,7 @@ public class ProviderFileLoader implements ProviderLoader {
}
eventType = parser.next();
}
while (eventType != XmlPullParser.END_DOCUMENT);
while (eventType != XmlPullParser.Event.END_DOCUMENT);
}
catch (Exception e) {
LOGGER.log(Level.SEVERE, "Unknown error occurred while parsing provider file", e);

+ 1
- 1
smack-core/src/main/java/org/jivesoftware/smack/provider/TlsFailureProvider.java View File

@ -19,7 +19,7 @@ package org.jivesoftware.smack.provider;
import org.jivesoftware.smack.packet.TlsProceed;
import org.jivesoftware.smack.packet.XmlEnvironment;
import org.xmlpull.v1.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParser;
public final class TlsFailureProvider extends NonzaProvider<TlsProceed> {

+ 1
- 1
smack-core/src/main/java/org/jivesoftware/smack/provider/TlsProceedProvider.java View File

@ -19,7 +19,7 @@ package org.jivesoftware.smack.provider;
import org.jivesoftware.smack.packet.TlsFailure;
import org.jivesoftware.smack.packet.XmlEnvironment;
import org.xmlpull.v1.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParser;
public final class TlsProceedProvider extends NonzaProvider<TlsFailure> {

+ 164
- 233
smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java View File

@ -17,18 +17,19 @@
package org.jivesoftware.smack.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.compress.packet.Compress;
import org.jivesoftware.smack.packet.EmptyResultIQ;
import org.jivesoftware.smack.packet.ErrorIQ;
@ -49,11 +50,11 @@ import org.jivesoftware.smack.provider.ExtensionElementProvider;
import org.jivesoftware.smack.provider.IQProvider;
import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smack.sasl.packet.SaslStreamElements.SASLFailure;
import org.jivesoftware.smack.xml.SmackXmlParser;
import org.jivesoftware.smack.xml.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParserException;
import org.jxmpp.jid.Jid;
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
@ -64,51 +65,27 @@ import org.xmlpull.v1.XmlPullParserFactory;
public class PacketParserUtils {
private static final Logger LOGGER = Logger.getLogger(PacketParserUtils.class.getName());
public static final String FEATURE_XML_ROUNDTRIP = "http://xmlpull.org/v1/doc/features.html#xml-roundtrip";
private static final XmlPullParserFactory XML_PULL_PARSER_FACTORY;
/**
* True if the XmlPullParser supports the XML_ROUNDTRIP feature.
*/
public static final boolean XML_PULL_PARSER_SUPPORTS_ROUNDTRIP;
static {
// Ensure that Smack is initialized.
SmackConfiguration.getVersion();
// TODO: Rename argument name from 'stanza' to 'element'.
public static XmlPullParser getParserFor(String stanza) throws XmlPullParserException, IOException {
return getParserFor(new StringReader(stanza));
}
XmlPullParser xmlPullParser;
boolean roundtrip = false;
public static XmlPullParser getParserFor(InputStream inputStream) throws XmlPullParserException {
InputStreamReader inputStreamReader;
try {
XML_PULL_PARSER_FACTORY = XmlPullParserFactory.newInstance();
xmlPullParser = XML_PULL_PARSER_FACTORY.newPullParser();
try {
xmlPullParser.setFeature(FEATURE_XML_ROUNDTRIP, true);
// We could successfully set the feature
roundtrip = true;
} catch (XmlPullParserException e) {
// Doesn't matter if FEATURE_XML_ROUNDTRIP isn't available
LOGGER.log(Level.FINEST, "XmlPullParser does not support XML_ROUNDTRIP", e);
}
}
catch (XmlPullParserException e) {
// Something really bad happened
inputStreamReader = new InputStreamReader(inputStream, StringUtils.UTF8);
} catch (UnsupportedEncodingException e) {
throw new AssertionError(e);
}
XML_PULL_PARSER_SUPPORTS_ROUNDTRIP = roundtrip;
}
// TODO: Rename argument name from 'stanza' to 'element'.
public static XmlPullParser getParserFor(String stanza) throws XmlPullParserException, IOException {
return getParserFor(new StringReader(stanza));
return SmackXmlParser.newXmlParser(inputStreamReader);
}
public static XmlPullParser getParserFor(Reader reader) throws XmlPullParserException, IOException {
XmlPullParser parser = newXmppParser(reader);
XmlPullParser parser = SmackXmlParser.newXmlParser(reader);
// Wind the parser forward to the first start tag
int event = parser.getEventType();
while (event != XmlPullParser.START_TAG) {
if (event == XmlPullParser.END_DOCUMENT) {
XmlPullParser.Event event = parser.getEventType();
while (event != XmlPullParser.Event.START_ELEMENT) {
if (event == XmlPullParser.Event.END_DOCUMENT) {
throw new IllegalArgumentException("Document contains no start tag");
}
event = parser.next();
@ -116,26 +93,6 @@ public class PacketParserUtils {
return parser;
}
public static XmlPullParser getParserFor(String stanza, String startTag)
throws XmlPullParserException, IOException {
XmlPullParser parser = getParserFor(stanza);
while (true) {
int event = parser.getEventType();
String name = parser.getName();
if (event == XmlPullParser.START_TAG && name.equals(startTag)) {
break;
}
else if (event == XmlPullParser.END_DOCUMENT) {
throw new IllegalArgumentException("Could not find start tag '" + startTag
+ "' in stanza: " + stanza);
}
parser.next();
}
return parser;
}
@SuppressWarnings("unchecked")
public static <S extends Stanza> S parseStanza(String stanza) throws Exception {
return (S) parseStanza(getParserFor(stanza), null);
@ -166,53 +123,6 @@ public class PacketParserUtils {
}
}
/**
* Creates a new XmlPullParser suitable for parsing XMPP. This means in particular that
* FEATURE_PROCESS_NAMESPACES is enabled.
* <p>
* Note that not all XmlPullParser implementations will return a String on
* <code>getText()</code> if the parser is on START_TAG or END_TAG. So you must not rely on this
* behavior when using the parser.
* </p>
*
* @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);
if (XML_PULL_PARSER_SUPPORTS_ROUNDTRIP) {
try {
parser.setFeature(FEATURE_XML_ROUNDTRIP, true);
}
catch (XmlPullParserException e) {
LOGGER.log(Level.SEVERE,
"XmlPullParser does not support XML_ROUNDTRIP, although it was first determined to be supported",
e);
}
}
return parser;
}
/**
* Creates a new XmlPullParser suitable for parsing XMPP. This means in particular that
* FEATURE_PROCESS_NAMESPACES is enabled.
* <p>
* Note that not all XmlPullParser implementations will return a String on
* <code>getText()</code> if the parser is on START_TAG or END_TAG. So you must not rely on this
* behavior when using the parser.
* </p>
*
* @param reader
* @return A suitable XmlPullParser for XMPP parsing
* @throws XmlPullParserException
*/
public static XmlPullParser newXmppParser(Reader reader) throws XmlPullParserException {
XmlPullParser parser = newXmppParser();
parser.setInput(reader);
return parser;
}
public static Message parseMessage(XmlPullParser parser) throws XmlPullParserException, IOException, SmackParsingException {
return parseMessage(parser, null);
}
@ -249,9 +159,9 @@ public class PacketParserUtils {
// in arbitrary sub-elements.
String thread = null;
outerloop: while (true) {
int eventType = parser.next();
XmlPullParser.Event eventType = parser.next();
switch (eventType) {
case XmlPullParser.START_TAG:
case START_ELEMENT:
String elementName = parser.getName();
String namespace = parser.getNamespace();
switch (elementName) {
@ -276,11 +186,12 @@ public class PacketParserUtils {
break;
}
break;
case XmlPullParser.END_TAG:
case END_ELEMENT:
if (parser.getDepth() == initialDepth) {
break outerloop;
}
break;
default: // fall out
}
}
@ -295,9 +206,9 @@ public class PacketParserUtils {
/**
* Returns the textual content of an element as String. After this method returns the parser
* position will be END_TAG, following the established pull parser calling convention.
* position will be END_ELEMENT, following the established pull parser calling convention.
* <p>
* The parser must be positioned on a START_TAG of an element which MUST NOT contain Mixed
* The parser must be positioned on a START_ELEMENT of an element which MUST NOT contain Mixed
* Content (as defined in XML 3.2.2), or else an XmlPullParserException will be thrown.
* </p>
* This method is used for the parts where the XMPP specification requires elements that contain
@ -309,41 +220,36 @@ public class PacketParserUtils {
* @throws IOException
*/
public static String parseElementText(XmlPullParser parser) throws XmlPullParserException, IOException {
assert (parser.getEventType() == XmlPullParser.START_TAG);
assert (parser.getEventType() == XmlPullParser.Event.START_ELEMENT);
String res;
if (parser.isEmptyElementTag()) {
res = "";
}
else {
// Advance to the text of the Element
int event = parser.next();
if (event != XmlPullParser.TEXT) {
if (event == XmlPullParser.END_TAG) {
// Assume this is the end tag of the start tag at the
// beginning of this method. Typical examples where this
// happens are body elements containing the empty string,
// ie. <body></body>, which appears to be valid XMPP, or a
// least it's not explicitly forbidden by RFC 6121 5.2.3
return "";
} else {
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) {
// Advance to the text of the Element
XmlPullParser.Event event = parser.next();
if (event != XmlPullParser.Event.TEXT_CHARACTERS) {
if (event == XmlPullParser.Event.END_ELEMENT) {
// Assume this is the end tag of the start tag at the
// beginning of this method. Typical examples where this
// happens are body elements containing the empty string,
// ie. <body></body>, which appears to be valid XMPP, or a
// least it's not explicitly forbidden by RFC 6121 5.2.3
return "";
} else {
throw new XmlPullParserException(
"Non-empty element tag contains child-elements, while Mixed Content (XML 3.2.2) is disallowed");
"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.Event.END_ELEMENT) {
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.
* <p>
* The parser must be positioned on START_TAG.
* The parser must be positioned on START_ELEMENT.
* </p>
* Note that only the outermost namespace attributes ("xmlns") will be returned, not nested ones.
*
@ -359,37 +265,10 @@ public class PacketParserUtils {
public static CharSequence parseElement(XmlPullParser parser,
boolean fullNamespaces) throws XmlPullParserException,
IOException {
assert (parser.getEventType() == XmlPullParser.START_TAG);
assert (parser.getEventType() == XmlPullParser.Event.START_ELEMENT);
return parseContentDepth(parser, parser.getDepth(), fullNamespaces);
}
/**
* Returns the content of a element.
* <p>
* 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.
* </p>
* 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
* @throws XmlPullParserException if parser encounters invalid XML
* @throws IOException if an IO error occurs
*/
public static CharSequence parseContent(XmlPullParser parser)
throws XmlPullParserException, IOException {
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(), false);
}
public static CharSequence parseContentDepth(XmlPullParser parser, int depth)
throws XmlPullParserException, IOException {
return parseContentDepth(parser, depth, false);
@ -402,7 +281,7 @@ public class PacketParserUtils {
* parent elements will be added to child elements that don't define a different namespace.
* <p>
* This method is able to parse the content with MX- and KXmlParser. KXmlParser does not support
* xml-roundtrip. i.e. return a String on getText() on START_TAG and END_TAG. We check for the
* xml-roundtrip. i.e. return a String on getText() on START_ELEMENT and END_ELEMENT. We check for the
* XML_ROUNDTRIP feature. If it's not found we are 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, if <code>fullNamespaces</code> is set to false.
@ -419,7 +298,7 @@ public class PacketParserUtils {
* @throws IOException
*/
public static CharSequence parseContentDepth(XmlPullParser parser, int depth, boolean fullNamespaces) throws XmlPullParserException, IOException {
if (parser.getFeature(FEATURE_XML_ROUNDTRIP)) {
if (parser.supportsRoundtrip()) {
return parseContentDepthWithRoundtrip(parser, depth, fullNamespaces);
} else {
return parseContentDepthWithoutRoundtrip(parser, depth, fullNamespaces);
@ -429,15 +308,21 @@ public class PacketParserUtils {
private static CharSequence parseContentDepthWithoutRoundtrip(XmlPullParser parser, int depth,
boolean fullNamespaces) throws XmlPullParserException, IOException {
XmlStringBuilder xml = new XmlStringBuilder();
int event = parser.getEventType();
boolean isEmptyElement = false;
XmlPullParser.Event event = parser.getEventType();
// 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;
boolean startElementJustSeen = false;
outerloop: while (true) {
switch (event) {
case XmlPullParser.START_TAG:
case START_ELEMENT:
if (startElementJustSeen) {
xml.rightAngleBracket();
}
else {
startElementJustSeen = true;
}
xml.halfOpenElement(parser.getName());
if (namespaceElement == null || fullNamespaces) {
String namespace = parser.getNamespace();
@ -449,18 +334,11 @@ public class PacketParserUtils {
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.rightAngleBracket();
}
break;
case XmlPullParser.END_TAG:
if (isEmptyElement) {
// Do nothing as the element was already closed, just reset the flag
isEmptyElement = false;
case END_ELEMENT:
if (startElementJustSeen) {
xml.closeEmptyElement();
startElementJustSeen = false;
}
else {
xml.closeElement(parser.getName());
@ -474,9 +352,16 @@ public class PacketParserUtils {
break outerloop;
}
break;