Browse Source

SmackReactor/NIO, Java8/Android19, Pretty print XML, FSM connections

This commit adds
- SmackReactor / NIO
- a framework for finite state machine connections
- support for Java 8
- pretty printed XML debug output

It also
- reworks the integration test framework
- raises the minimum Android API level to 19
- introduces XmppNioTcpConnection

Furthermore fixes SMACK-801 (at least partly). Java 8 language
features are available, but not all runtime library methods. For that
we would need to raise the Android API level to 24 or higher.
staleness
Florian Schmaus 1 year ago
parent
commit
e98d42790a
100 changed files with 6248 additions and 1171 deletions
  1. +37
    -3
      build.gradle
  2. +281
    -261
      resources/eclipse/smack_formatter.xml
  3. +0
    -12
      smack-bosh/src/main/java/org/jivesoftware/smack/bosh/XMPPBOSHConnection.java
  4. +328
    -38
      smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java
  5. +54
    -0
      smack-core/src/main/java/org/jivesoftware/smack/AbstractXmppNioConnection.java
  6. +36
    -0
      smack-core/src/main/java/org/jivesoftware/smack/GenericElementListener.java
  7. +2
    -3
      smack-core/src/main/java/org/jivesoftware/smack/Manager.java
  8. +176
    -0
      smack-core/src/main/java/org/jivesoftware/smack/NonzaCallback.java
  9. +4
    -1
      smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java
  10. +66
    -0
      smack-core/src/main/java/org/jivesoftware/smack/ScheduledAction.java
  11. +24
    -2
      smack-core/src/main/java/org/jivesoftware/smack/SmackException.java
  12. +13
    -0
      smack-core/src/main/java/org/jivesoftware/smack/SmackInitialization.java
  13. +440
    -0
      smack-core/src/main/java/org/jivesoftware/smack/SmackReactor.java
  14. +62
    -34
      smack-core/src/main/java/org/jivesoftware/smack/StanzaCollector.java
  15. +20
    -3
      smack-core/src/main/java/org/jivesoftware/smack/SynchronizationPoint.java
  16. +2
    -2
      smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java
  17. +4
    -0
      smack-core/src/main/java/org/jivesoftware/smack/XMPPException.java
  18. +76
    -0
      smack-core/src/main/java/org/jivesoftware/smack/XmppInputOutputFilter.java
  19. +1
    -1
      smack-core/src/main/java/org/jivesoftware/smack/compress/packet/Compress.java
  20. +89
    -0
      smack-core/src/main/java/org/jivesoftware/smack/compress/packet/Failure.java
  21. +36
    -0
      smack-core/src/main/java/org/jivesoftware/smack/compress/provider/CompressedProvider.java
  22. +81
    -0
      smack-core/src/main/java/org/jivesoftware/smack/compress/provider/FailureProvider.java
  23. +21
    -0
      smack-core/src/main/java/org/jivesoftware/smack/compress/provider/package-info.java
  24. +5
    -1
      smack-core/src/main/java/org/jivesoftware/smack/compression/XMPPInputOutputStream.java
  25. +47
    -0
      smack-core/src/main/java/org/jivesoftware/smack/compression/XmppCompressionFactory.java
  26. +65
    -0
      smack-core/src/main/java/org/jivesoftware/smack/compression/XmppCompressionManager.java
  27. +287
    -0
      smack-core/src/main/java/org/jivesoftware/smack/compression/zlib/ZlibXmppCompressionFactory.java
  28. +21
    -0
      smack-core/src/main/java/org/jivesoftware/smack/compression/zlib/package-info.java
  29. +4
    -14
      smack-core/src/main/java/org/jivesoftware/smack/debugger/AbstractDebugger.java
  30. +57
    -2
      smack-core/src/main/java/org/jivesoftware/smack/debugger/SmackDebugger.java
  31. +816
    -0
      smack-core/src/main/java/org/jivesoftware/smack/fsm/AbstractXmppStateMachineConnection.java
  32. +113
    -0
      smack-core/src/main/java/org/jivesoftware/smack/fsm/ConnectionStateEvent.java
  33. +24
    -0
      smack-core/src/main/java/org/jivesoftware/smack/fsm/ConnectionStateMachineListener.java
  34. +33
    -0
      smack-core/src/main/java/org/jivesoftware/smack/fsm/LoginContext.java
  35. +221
    -0
      smack-core/src/main/java/org/jivesoftware/smack/fsm/StateDescriptor.java
  36. +419
    -0
      smack-core/src/main/java/org/jivesoftware/smack/fsm/StateDescriptorGraph.java
  37. +60
    -0
      smack-core/src/main/java/org/jivesoftware/smack/fsm/StateMachineException.java
  38. +21
    -0
      smack-core/src/main/java/org/jivesoftware/smack/fsm/package-info.java
  39. +2
    -10
      smack-core/src/main/java/org/jivesoftware/smack/packet/ExtensionElement.java
  40. +28
    -0
      smack-core/src/main/java/org/jivesoftware/smack/packet/FullyQualifiedElement.java
  41. +1
    -1
      smack-core/src/main/java/org/jivesoftware/smack/packet/Nonza.java
  42. +4
    -2
      smack-core/src/main/java/org/jivesoftware/smack/packet/StartTls.java
  43. +42
    -0
      smack-core/src/main/java/org/jivesoftware/smack/packet/StreamClose.java
  44. +43
    -0
      smack-core/src/main/java/org/jivesoftware/smack/packet/TlsFailure.java
  45. +43
    -0
      smack-core/src/main/java/org/jivesoftware/smack/packet/TlsProceed.java
  46. +1
    -2
      smack-core/src/main/java/org/jivesoftware/smack/packet/TopLevelStreamElement.java
  47. +24
    -0
      smack-core/src/main/java/org/jivesoftware/smack/provider/NonzaProvider.java
  48. +23
    -0
      smack-core/src/main/java/org/jivesoftware/smack/provider/Provider.java
  49. +28
    -0
      smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderManager.java
  50. +35
    -0
      smack-core/src/main/java/org/jivesoftware/smack/provider/TlsFailureProvider.java
  51. +35
    -0
      smack-core/src/main/java/org/jivesoftware/smack/provider/TlsProceedProvider.java
  52. +13
    -0
      smack-core/src/main/java/org/jivesoftware/smack/util/ArrayBlockingQueueWithShutdown.java
  53. +1
    -1
      smack-core/src/main/java/org/jivesoftware/smack/util/Async.java
  54. +20
    -1
      smack-core/src/main/java/org/jivesoftware/smack/util/CollectionUtil.java
  55. +28
    -1
      smack-core/src/main/java/org/jivesoftware/smack/util/MultiMap.java
  56. +1
    -0
      smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java
  57. +1
    -1
      smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java
  58. +39
    -0
      smack-core/src/main/java/org/jivesoftware/smack/util/UTF8.java
  59. +8
    -2
      smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java
  60. +45
    -0
      smack-core/src/main/java/org/jivesoftware/smack/util/XmppElementUtil.java
  61. +9
    -0
      smack-core/src/main/java/org/jivesoftware/smack/util/dns/HostAddress.java
  62. +5
    -1
      smack-core/src/main/java/org/jivesoftware/smack/util/dns/SmackDaneVerifier.java
  63. +2
    -2
      smack-core/src/test/java/org/jivesoftware/smack/DummyConnection.java
  64. +49
    -34
      smack-core/src/test/java/org/jivesoftware/smack/StanzaCollectorTest.java
  65. +58
    -0
      smack-core/src/test/java/org/jivesoftware/smack/compress/packet/FailureTest.java
  66. +56
    -0
      smack-core/src/test/java/org/jivesoftware/smack/compress/provider/FailureProviderTest.java
  67. +4
    -12
      smack-debug-slf4j/src/main/java/org/jivesoftware/smackx/debugger/slf4j/SLF4JSmackDebugger.java
  68. +4
    -12
      smack-debug/src/main/java/org/jivesoftware/smackx/debugger/EnhancedDebugger.java
  69. +4
    -12
      smack-debug/src/main/java/org/jivesoftware/smackx/debugger/LiteDebugger.java
  70. +3
    -4
      smack-experimental/src/main/java/org/jivesoftware/smackx/gcm/provider/GcmExtensionProvider.java
  71. +4
    -4
      smack-experimental/src/main/java/org/jivesoftware/smackx/json/provider/AbstractJsonExtensionProvider.java
  72. +3
    -4
      smack-experimental/src/main/java/org/jivesoftware/smackx/json/provider/JsonExtensionProvider.java
  73. +26
    -43
      smack-extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java
  74. +1
    -3
      smack-im/src/test/java/org/jivesoftware/smack/roster/RosterVersioningTest.java
  75. +1
    -1
      smack-integration-test/build.gradle
  76. +266
    -0
      smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java
  77. +5
    -5
      smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/AbstractSmackIntTest.java
  78. +15
    -3
      smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/AbstractSmackIntegrationTest.java
  79. +32
    -24
      smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/AbstractSmackLowLevelIntegrationTest.java
  80. +63
    -0
      smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/AbstractSmackSpecificLowLevelIntegrationTest.java
  81. +34
    -1
      smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java
  82. +23
    -0
      smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/ConnectionConfigurationBuilderApplier.java
  83. +3
    -4
      smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/FailedTest.java
  84. +0
    -241
      smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/IntTestUtil.java
  85. +7
    -1
      smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTest.java
  86. +9
    -10
      smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestEnvironment.java
  87. +405
    -307
      smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java
  88. +3
    -4
      smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SuccessfulTest.java
  89. +3
    -4
      smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/TestNotPossible.java
  90. +4
    -5
      smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/TestResult.java
  91. +104
    -0
      smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/XmppConnectionDescriptor.java
  92. +441
    -0
      smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/XmppConnectionManager.java
  93. +2
    -2
      smack-integration-test/src/main/java/org/jivesoftware/smack/ChatTest.java
  94. +5
    -8
      smack-integration-test/src/main/java/org/jivesoftware/smack/LoginIntegrationTest.java
  95. +10
    -13
      smack-integration-test/src/main/java/org/jivesoftware/smack/StreamManagementTest.java
  96. +4
    -6
      smack-integration-test/src/main/java/org/jivesoftware/smack/WaitForClosingStreamElementTest.java
  97. +67
    -0
      smack-integration-test/src/main/java/org/jivesoftware/smack/XmppConnectionIntegrationTest.java
  98. +1
    -1
      smack-integration-test/src/main/java/org/jivesoftware/smack/chat2/AbstractChatIntegrationTest.java
  99. +1
    -1
      smack-integration-test/src/main/java/org/jivesoftware/smack/chat2/IncomingMessageListenerIntegrationTest.java
  100. +1
    -1
      smack-integration-test/src/main/java/org/jivesoftware/smack/chat2/OutgoingMessageListenerIntegrationTest.java

+ 37
- 3
build.gradle View File

@@ -102,7 +102,7 @@ allprojects {
junitVersion = '5.2.0'
}
group = 'org.igniterealtime.smack'
sourceCompatibility = 1.7
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = sourceCompatibility
version = shortVersion
if (isSnapshot) {
@@ -245,7 +245,14 @@ gradle.taskGraph.whenReady { taskGraph ->
}
}

task javadocAll(type: Javadoc) {
task copyAllJavadocDocFiles(type: Copy) {
from javadocAllProjects.collect { project ->
"${project.projectDir}/src/javadoc" }
into javadocAllDir
include '**/doc-files/*.*'
}

task javadocAll(type: Javadoc, dependsOn: copyAllJavadocDocFiles) {
source javadocAllProjects.collect {project ->
project.sourceSets.main.allJava }
destinationDir = javadocAllDir
@@ -449,12 +456,39 @@ subprojects {
enabled false
semver false
}

// Work around https://github.com/gradle/gradle/issues/4046
javadoc.dependsOn('copyJavadocDocFiles')
task copyJavadocDocFiles(type: Copy) {
from('src/javadoc')
into 'build/docs/javadoc'
include '**/doc-files/*.*'
}

// If this subproject has a Makefile then make copyJavadocDocFiles
// and the root project's javadocAll task dependend on
// generateFiles.
if (file("$projectDir/Makefile").exists()) {
copyJavadocDocFiles.dependsOn('generateFiles')
rootProject.copyAllJavadocDocFiles.dependsOn("${project.name}:generateFiles")
task generateFiles(type: Exec) {
workingDir projectDir
commandLine 'make'
}

clean.dependsOn('cleanGeneratedFiles')
rootProject.clean.dependsOn("${project.name}:cleanGeneratedFiles")
task cleanGeneratedFiles(type: Exec) {
workingDir projectDir
commandLine 'make', 'clean'
}
}
}

configure (androidProjects + androidBootClasspathProjects) {
apply plugin: 'ru.vyarus.animalsniffer'
dependencies {
signature "net.sf.androidscents.signature:android-api-level-${smackMinAndroidSdk}:2.3.1_r2@signature"
signature "net.sf.androidscents.signature:android-api-level-${smackMinAndroidSdk}:4.4.2_r4@signature"
}
animalsniffer {
sourceSets = [sourceSets.main]


+ 281
- 261
resources/eclipse/smack_formatter.xml View File

@@ -1,295 +1,315 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="12">
<profile kind="CodeFormatterProfile" name="Smack" version="12">
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<profiles version="13">
<profile kind="CodeFormatterProfile" name="Smack" version="13">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="48"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="120"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.compiler.source" value="1.8"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.compiler.source" value="9"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.8"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="9"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="48"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="120"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.8"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.compliance" value="9"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
</profile>
</profiles>

+ 0
- 12
smack-bosh/src/main/java/org/jivesoftware/smack/bosh/XMPPBOSHConnection.java View File

@@ -387,18 +387,6 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
readerConsumer.start();
}

/**
* Sends out a notification that there was an error with the connection
* and closes the connection.
*
* @param e the exception that causes the connection close event.
*/
protected void notifyConnectionError(Exception e) {
// Closes the connection temporary. A reconnection is possible
shutdown();
callConnectionClosedOnErrorListener(e);
}

/**
* A listener class which listen for a successfully established connection
* and connection errors and notifies the BOSHConnection.


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

@@ -1,6 +1,6 @@
/**
*
* Copyright 2009 Jive Software.
* Copyright 2009 Jive Software, 2018 Florian Schmaus.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,23 @@
*/
package org.jivesoftware.smack;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Constructor;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.Security;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -33,8 +47,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
@@ -43,6 +55,16 @@ import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.PasswordCallback;

import org.jivesoftware.smack.ConnectionConfiguration.DnssecMode;
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.jivesoftware.smack.SmackConfiguration.UnknownIqRequestReplyMode;
import org.jivesoftware.smack.SmackException.AlreadyConnectedException;
@@ -54,6 +76,7 @@ import org.jivesoftware.smack.SmackException.ResourceBindingNotOfferedException;
import org.jivesoftware.smack.SmackException.SecurityRequiredByClientException;
import org.jivesoftware.smack.SmackException.SecurityRequiredException;
import org.jivesoftware.smack.SmackFuture.InternalSmackFuture;
import org.jivesoftware.smack.XMPPException.FailedNonzaException;
import org.jivesoftware.smack.XMPPException.StreamErrorException;
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.compress.packet.Compress;
@@ -67,6 +90,7 @@ import org.jivesoftware.smack.iqrequest.IQRequestHandler;
import org.jivesoftware.smack.packet.Bind;
import org.jivesoftware.smack.packet.ErrorIQ;
import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.packet.FullyQualifiedElement;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Mechanisms;
import org.jivesoftware.smack.packet.Message;
@@ -77,8 +101,11 @@ import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.packet.StanzaError;
import org.jivesoftware.smack.packet.StartTls;
import org.jivesoftware.smack.packet.StreamError;
import org.jivesoftware.smack.packet.StreamOpen;
import org.jivesoftware.smack.packet.TopLevelStreamElement;
import org.jivesoftware.smack.parsing.ParsingExceptionCallback;
import org.jivesoftware.smack.provider.ExtensionElementProvider;
import org.jivesoftware.smack.provider.NonzaProvider;
import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smack.sasl.core.SASLAnonymous;
import org.jivesoftware.smack.util.DNSUtil;
@@ -87,6 +114,8 @@ import org.jivesoftware.smack.util.PacketParserUtils;
import org.jivesoftware.smack.util.ParserUtils;
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.jxmpp.jid.DomainBareJid;
import org.jxmpp.jid.EntityFullJid;
@@ -132,6 +161,12 @@ import org.xmlpull.v1.XmlPullParser;
public abstract class AbstractXMPPConnection implements XMPPConnection {
private static final Logger LOGGER = Logger.getLogger(AbstractXMPPConnection.class.getName());

protected static final SmackReactor SMACK_REACTOR;

static {
SMACK_REACTOR = SmackReactor.getInstance();
}

/**
* Counter to uniquely identify connections that are created.
*/
@@ -186,9 +221,11 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
private final Map<StanzaListener, InterceptorWrapper> interceptors =
new HashMap<>();

final Map<String, NonzaCallback> nonzaCallbacks = new HashMap<>();

protected final Lock connectionLock = new ReentrantLock();

protected final Map<String, ExtensionElement> streamFeatures = new HashMap<>();
protected final Map<String, FullyQualifiedElement> streamFeatures = new HashMap<>();

/**
* The full JID of the authenticated user, as returned by the resource binding response of the server.
@@ -244,6 +281,14 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
protected final SynchronizationPoint<XMPPException> saslFeatureReceived = new SynchronizationPoint<>(
AbstractXMPPConnection.this, "SASL mechanisms stream feature from server");


/**
* A synchronization point which is successful if this connection has received the closing
* stream element from the remote end-point, i.e. the server.
*/
protected final SynchronizationPoint<Exception> closingStreamReceived = new SynchronizationPoint<>(
this, "stream closing element received");

/**
* The SASLAuthentication manager that is responsible for authenticating with the server.
*/
@@ -269,20 +314,6 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {

private ParsingExceptionCallback parsingExceptionCallback = SmackConfiguration.getDefaultParsingExceptionCallback();

/**
* This scheduled thread pool executor is used to remove pending callbacks.
*/
protected static final ScheduledExecutorService SCHEDULED_EXECUTOR_SERVICE = Executors.newSingleThreadScheduledExecutor(
new ThreadFactory() {
@Override
public Thread newThread(Runnable runnable) {
Thread thread = new Thread(runnable);
thread.setName("Smack Scheduled Executor Service");
thread.setDaemon(true);
return thread;
}
});

/**
* A cached thread pool executor service with custom thread factory to set meaningful names on the threads and set
* them 'daemon'.
@@ -297,7 +328,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
}
});

private static final AsyncButOrdered<AbstractXMPPConnection> ASYNC_BUT_ORDERED = new AsyncButOrdered<>();
protected static final AsyncButOrdered<AbstractXMPPConnection> ASYNC_BUT_ORDERED = new AsyncButOrdered<>();

/**
* The used host to establish the connection to
@@ -320,6 +351,8 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
*/
protected boolean wasAuthenticated = false;

protected Exception currentConnectionException;

private final Map<String, IQRequestHandler> setIqRequestHandler = new HashMap<>();
private final Map<String, IQRequestHandler> getIqRequestHandler = new HashMap<>();

@@ -566,7 +599,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
return streamId;
}

protected void bindResourceAndEstablishSession(Resourcepart resource) throws XMPPErrorException,
protected Resourcepart bindResourceAndEstablishSession(Resourcepart resource) throws XMPPErrorException,
SmackException, InterruptedException {

// Wait until either:
@@ -602,6 +635,8 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
packetCollector = createStanzaCollectorAndSend(new StanzaIdFilter(session), session);
packetCollector.nextResultOrThrow();
}

return response.getJid().getResourcepart();
}

protected void afterSuccessfulLogin(final boolean resumed) throws NotConnectedException, InterruptedException {
@@ -703,6 +738,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
}
}

// TODO: This method should be final.
@Override
public void sendStanza(Stanza stanza) throws NotConnectedException, InterruptedException {
Objects.requireNonNull(stanza, "Stanza must not be null");
@@ -781,11 +817,61 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
callConnectionClosedListener();
}

/**
* Sends out a notification that there was an error with the connection
* and closes the connection.
*
* @param exception the exception that causes the connection close event.
*/
protected final synchronized void notifyConnectionError(Exception exception) {
if (!isConnected()) {
LOGGER.log(Level.INFO, "Connection was already disconnected when attempting to handle " + exception,
exception);
return;
}

currentConnectionException = exception;
notifyAll();

for (StanzaCollector collector : collectors) {
collector.notifyConnectionError(exception);
}
// TODO: We should also notify things like the SASL authentication machinery about the exception.

// Closes the connection temporary. A if the connection supports stream management, then a reconnection is
// possible. Note that a connection listener of e.g. XMPPTCPConnection will drop the SM state in
// case the Exception is a StreamErrorException.
instantShutdown();

callConnectionClosedOnErrorListener(exception);
}

protected void instantShutdown() {
// Default implementation simply calls shutdown(), subclasses may override this.
shutdown();
}

/**
* Shuts the current connection down.
*/
protected abstract void shutdown();

protected final boolean waitForClosingStreamTagFromServer() {
Exception exception;
try {
// After we send the closing stream element, check if there was already a
// closing stream element sent by the server or wait with a timeout for a
// closing stream element to be received from the server.
exception = closingStreamReceived.checkIfSuccessOrWait();
} catch (InterruptedException | NoResponseException e) {
exception = e;
}
if (exception != null) {
LOGGER.log(Level.INFO, "Exception while waiting for closing stream element from the server " + this, exception);
}
return exception == null;
}

@Override
public void addConnectionListener(ConnectionListener connectionListener) {
if (connectionListener == null) {
@@ -910,20 +996,25 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
}

/**
* Process all stanza listeners for sending packets.
* Process all stanza listeners for sending stanzas.
* <p>
* Compared to {@link #firePacketInterceptors(Stanza)}, the listeners will be invoked in a new thread.
* </p>
*
* @param packet the stanza to process.
* @param sendTopLevelStreamElement the top level stream element which just got send.
*/
// TODO: Rename to fireElementSendingListeners().
@SuppressWarnings("javadoc")
protected void firePacketSendingListeners(final Stanza packet) {
final SmackDebugger debugger = this.debugger;
protected void firePacketSendingListeners(final TopLevelStreamElement sendTopLevelStreamElement) {
if (debugger != null) {
debugger.onOutgoingStreamElement(packet);
debugger.onOutgoingStreamElement(sendTopLevelStreamElement);
}

if (!(sendTopLevelStreamElement instanceof Stanza)) {
return;
}
Stanza packet = (Stanza) sendTopLevelStreamElement;

final List<StanzaListener> listenersToNotify = new LinkedList<>();
synchronized (sendListeners) {
for (ListenerWrapper listenerWrapper : sendListeners.values()) {
@@ -1037,6 +1128,49 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
this.unknownIqRequestReplyMode = Objects.requireNonNull(unknownIqRequestReplyMode, "Mode must not be null");
}

protected final NonzaCallback.Builder buildNonzaCallback() {
return new NonzaCallback.Builder(this);
}

protected <SN extends Nonza, FN extends Nonza> SN sendAndWaitForResponse(Nonza nonza, Class<SN> successNonzaClass,
Class<FN> failedNonzaClass)
throws NoResponseException, NotConnectedException, InterruptedException, FailedNonzaException {
NonzaCallback.Builder builder = buildNonzaCallback();
SN successNonza = NonzaCallback.sendAndWaitForResponse(builder, nonza, successNonzaClass, failedNonzaClass);
return successNonza;
}

protected final void parseAndProcessNonza(XmlPullParser parser) throws SmackException {
final String element = parser.getName();
final String namespace = parser.getNamespace();
final String key = XmppStringUtils.generateKey(element, namespace);

NonzaProvider<? extends Nonza> nonzaProvider = ProviderManager.getNonzaProvider(key);
if (nonzaProvider == null) {
LOGGER.severe("Unknown nonza: " + key);
return;
}

NonzaCallback nonzaCallback;
synchronized (nonzaCallbacks) {
nonzaCallback = nonzaCallbacks.get(key);
}
if (nonzaCallback == null) {
LOGGER.info("No nonza callback for " + key);
return;
}

Nonza nonza;
try {
nonza = nonzaProvider.parse(parser);
}
catch (Exception e) {
throw new SmackException(e);
}

nonzaCallback.onNonzaReceived(nonza);
}

protected void parseAndProcessStanza(XmlPullParser parser) throws Exception {
ParserUtils.assertAtStartTag(parser);
int parserDepth = parser.getDepth();
@@ -1130,14 +1264,18 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {

// If the IQ stanza is of type "get" or "set" with no registered IQ request handler, then answer an
// IQ of type 'error' with condition 'service-unavailable'.
ErrorIQ errorIQ = IQ.createErrorResponse(iq, StanzaError.getBuilder(
final ErrorIQ errorIQ = IQ.createErrorResponse(iq, StanzaError.getBuilder(
replyCondition));
try {
sendStanza(errorIQ);
}
catch (InterruptedException | NotConnectedException e) {
LOGGER.log(Level.WARNING, "Exception while sending error IQ to unkown IQ request", e);
}
// Use async sendStanza() here, since if sendStanza() would block, then some connections, e.g.
// XmppNioTcpConnection, would deadlock, as this operation is performed in the same thread that is
asyncGo(() -> {
try {
sendStanza(errorIQ);
}
catch (InterruptedException | NotConnectedException e) {
LOGGER.log(Level.WARNING, "Exception while sending error IQ to unkown IQ request", e);
}
});
} else {
Executor executorService = null;
switch (iqRequestHandler.getMode()) {
@@ -1297,7 +1435,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
}
}

protected void callConnectionClosedOnErrorListener(Exception e) {
private void callConnectionClosedOnErrorListener(Exception e) {
boolean logWarning = true;
if (e instanceof StreamErrorException) {
StreamErrorException see = (StreamErrorException) e;
@@ -1401,7 +1539,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
int eventType = parser.next();

if (eventType == XmlPullParser.START_TAG && parser.getDepth() == initialDepth + 1) {
ExtensionElement streamFeature = null;
FullyQualifiedElement streamFeature = null;
String name = parser.getName();
String namespace = parser.getNamespace();
switch (name) {
@@ -1435,6 +1573,10 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
break;
}
}
}

protected final void parseFeaturesAndNotify(XmlPullParser parser) throws Exception {
parseFeatures(parser);

if (hasFeature(Mechanisms.ELEMENT, Mechanisms.NAMESPACE)) {
// Only proceed with SASL auth if TLS is disabled or if the server doesn't announce it
@@ -1465,7 +1607,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {

@SuppressWarnings("unchecked")
@Override
public <F extends ExtensionElement> F getFeature(String element, String namespace) {
public <F extends FullyQualifiedElement> F getFeature(String element, String namespace) {
return (F) streamFeatures.get(XmppStringUtils.generateKey(element, namespace));
}

@@ -1474,7 +1616,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
return getFeature(element, namespace) != null;
}

protected void addStreamFeature(ExtensionElement feature) {
protected void addStreamFeature(FullyQualifiedElement feature) {
String key = XmppStringUtils.generateKey(feature.getElementName(), feature.getNamespace());
streamFeatures.put(key, feature);
}
@@ -1659,7 +1801,155 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
CACHED_EXECUTOR_SERVICE.execute(runnable);
}

protected static ScheduledFuture<?> schedule(Runnable runnable, long delay, TimeUnit unit) {
return SCHEDULED_EXECUTOR_SERVICE.schedule(runnable, delay, unit);
protected static ScheduledAction schedule(Runnable runnable, long delay, TimeUnit unit) {
return SMACK_REACTOR.schedule(runnable, delay, unit);
}

protected void onStreamOpen(XmlPullParser parser) {
// We found an opening stream.
if ("jabber:client".equals(parser.getNamespace(null))) {
streamId = parser.getAttributeValue("", "id");
String reportedServerDomain = parser.getAttributeValue("", "from");
assert (config.getXMPPServiceDomain().equals(reportedServerDomain));
}
}

protected void sendStreamOpen() throws NotConnectedException, InterruptedException {
// If possible, provide the receiving entity of the stream open tag, i.e. the server, as much information as
// possible. The 'to' attribute is *always* available. The 'from' attribute if set by the user and no external
// mechanism is used to determine the local entity (user). And the 'id' attribute is available after the first
// response from the server (see e.g. RFC 6120 § 9.1.1 Step 2.)
CharSequence to = getXMPPServiceDomain();
CharSequence from = null;
CharSequence localpart = config.getUsername();
if (localpart != null) {
from = XmppStringUtils.completeJidFrom(localpart, to);
}
String id = getStreamId();
sendNonza(new StreamOpen(to, from, id));
}

public static final class SmackTlsContext {
public final SSLContext sslContext;
public final SmackDaneVerifier daneVerifier;

private SmackTlsContext(SSLContext sslContext, SmackDaneVerifier daneVerifier) {
assert sslContext != null;
this.sslContext = sslContext;
this.daneVerifier = daneVerifier;
}
}

protected final SmackTlsContext getSmackTlsContext() throws KeyManagementException, NoSuchAlgorithmException,
CertificateException, IOException, UnrecoverableKeyException, KeyStoreException, NoSuchProviderException {
SmackDaneVerifier daneVerifier = null;

if (config.getDnssecMode() == DnssecMode.needsDnssecAndDane) {
SmackDaneProvider daneProvider = DNSUtil.getDaneProvider();
if (daneProvider == null) {
throw new UnsupportedOperationException("DANE enabled but no SmackDaneProvider configured");
}
daneVerifier = daneProvider.newInstance();
if (daneVerifier == null) {
throw new IllegalStateException("DANE requested but DANE provider did not return a DANE verifier");
}
}

SSLContext context = this.config.getCustomSSLContext();
KeyStore ks = null;
PasswordCallback pcb = null;

if (context == null) {
final String keyStoreType = config.getKeystoreType();
final CallbackHandler callbackHandler = config.getCallbackHandler();
final String keystorePath = config.getKeystorePath();
if ("PKCS11".equals(keyStoreType)) {
try {
Constructor<?> c = Class.forName("sun.security.pkcs11.SunPKCS11").getConstructor(InputStream.class);
String pkcs11Config = "name = SmartCard\nlibrary = " + config.getPKCS11Library();
ByteArrayInputStream config = new ByteArrayInputStream(pkcs11Config.getBytes(StringUtils.UTF8));
Provider p = (Provider) c.newInstance(config);
Security.addProvider(p);
ks = KeyStore.getInstance("PKCS11",p);
pcb = new PasswordCallback("PKCS11 Password: ",false);
callbackHandler.handle(new Callback[] {pcb});
ks.load(null,pcb.getPassword());
}
catch (Exception e) {
LOGGER.log(Level.WARNING, "Exception", e);
ks = null;
}
}
else if ("Apple".equals(keyStoreType)) {
ks = KeyStore.getInstance("KeychainStore","Apple");
ks.load(null,null);
// pcb = new PasswordCallback("Apple Keychain",false);
// pcb.setPassword(null);
}
else if (keyStoreType != null) {
ks = KeyStore.getInstance(keyStoreType);
if (callbackHandler != null && StringUtils.isNotEmpty(keystorePath)) {
try {
pcb = new PasswordCallback("Keystore Password: ", false);
callbackHandler.handle(new Callback[] { pcb });
ks.load(new FileInputStream(keystorePath), pcb.getPassword());
}
catch (Exception e) {
LOGGER.log(Level.WARNING, "Exception", e);
ks = null;
}
} else {
ks.load(null, null);
}
}

KeyManager[] kms = null;

if (ks != null) {
String keyManagerFactoryAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
KeyManagerFactory kmf = null;
try {
kmf = KeyManagerFactory.getInstance(keyManagerFactoryAlgorithm);
}
catch (NoSuchAlgorithmException e) {
LOGGER.log(Level.FINE, "Could get the default KeyManagerFactory for the '"
+ keyManagerFactoryAlgorithm + "' algorithm", e);
}
if (kmf != null) {
try {
if (pcb == null) {
kmf.init(ks, null);
}
else {
kmf.init(ks, pcb.getPassword());
pcb.clearPassword();
}
kms = kmf.getKeyManagers();
}
catch (NullPointerException npe) {
LOGGER.log(Level.WARNING, "NullPointerException", npe);
}
}
}

// If the user didn't specify a SSLContext, use the default one
context = SSLContext.getInstance("TLS");

final SecureRandom secureRandom = new java.security.SecureRandom();
X509TrustManager customTrustManager = config.getCustomX509TrustManager();

if (daneVerifier != null) {
// User requested DANE verification.
daneVerifier.init(context, kms, customTrustManager, secureRandom);
} else {
TrustManager[] customTrustManagers = null;
if (customTrustManager != null) {
customTrustManagers = new TrustManager[] { customTrustManager };
}
context.init(kms, customTrustManagers, secureRandom);
}
}

return new SmackTlsContext(context, daneVerifier);
}
}

+ 54
- 0
smack-core/src/main/java/org/jivesoftware/smack/AbstractXmppNioConnection.java View File

@@ -0,0 +1,54 @@
/**
*
* Copyright 2018 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;

import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;

import org.jivesoftware.smack.SmackReactor.ChannelSelectedCallback;
import org.jivesoftware.smack.fsm.AbstractXmppStateMachineConnection;
import org.jivesoftware.smack.fsm.StateDescriptor;
import org.jivesoftware.smack.fsm.StateDescriptorGraph.GraphVertex;

public abstract class AbstractXmppNioConnection extends AbstractXmppStateMachineConnection {

protected AbstractXmppNioConnection(ConnectionConfiguration configuration, GraphVertex<StateDescriptor> initialStateDescriptorVertex) {
super(configuration, initialStateDescriptorVertex);
}

protected SelectionKey registerWithSelector(SelectableChannel channel, int ops, ChannelSelectedCallback callback)
throws ClosedChannelException {
return SMACK_REACTOR.registerWithSelector(channel, ops, callback);
}

/**
* Set the interest Ops of a SelectionKey. Since Java's NIO interestOps(int) can block at any time, we use a queue
* to perform the actual operation in the reactor where we can perform this operation non-blocking.
*
* @param selectionKey
* @param interestOps
*/
protected void setInterestOps(SelectionKey selectionKey, int interestOps) {
SMACK_REACTOR.setInterestOps(selectionKey, interestOps);
}

@Override
protected void finalize() {
disconnect();
}
}

+ 36
- 0
smack-core/src/main/java/org/jivesoftware/smack/GenericElementListener.java View File

@@ -0,0 +1,36 @@
/**
*
* Copyright 2018 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;

import org.jivesoftware.smack.packet.Element;

public abstract class GenericElementListener<E extends Element> {

private final Class<? extends E> elementClass;

public GenericElementListener(Class<? extends E> elementClass) {
this.elementClass = elementClass;
}

public abstract void process(E element);

public final void processElement(Element element) {
E concreteEleement = elementClass.cast(element);
process(concreteEleement);
}

}

+ 2
- 3
smack-core/src/main/java/org/jivesoftware/smack/Manager.java View File

@@ -17,7 +17,6 @@
package org.jivesoftware.smack;

import java.lang.ref.WeakReference;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.jivesoftware.smack.SmackException.NotLoggedInException;
@@ -54,7 +53,7 @@ public abstract class Manager {
return connection;
}

protected static final ScheduledFuture<?> schedule(Runnable runnable, long delay, TimeUnit unit) {
return AbstractXMPPConnection.SCHEDULED_EXECUTOR_SERVICE.schedule(runnable, delay, unit);
protected static final ScheduledAction schedule(Runnable runnable, long delay, TimeUnit unit) {
return AbstractXMPPConnection.SMACK_REACTOR.schedule(runnable, delay, unit);
}
}

+ 176
- 0
smack-core/src/main/java/org/jivesoftware/smack/NonzaCallback.java View File

@@ -0,0 +1,176 @@
/**
*
* Copyright 2018 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;

import java.util.HashMap;
import java.util.Map;

import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.XMPPException.FailedNonzaException;
import org.jivesoftware.smack.packet.Nonza;
import org.jivesoftware.smack.util.XmppElementUtil;

import org.jxmpp.util.XmppStringUtils;

public class NonzaCallback {

protected final AbstractXMPPConnection connection;
protected final Map<String, GenericElementListener<? extends Nonza>> filterAndListeners;

private NonzaCallback(Builder builder) {
this.connection = builder.connection;
this.filterAndListeners = builder.filterAndListeners;
install();
}

void onNonzaReceived(Nonza nonza) {
String key = XmppStringUtils.generateKey(nonza.getElementName(), nonza.getNamespace());
GenericElementListener<? extends Nonza> nonzaListener = filterAndListeners.get(key);

nonzaListener.processElement(nonza);
}

public void cancel() {
synchronized (connection.nonzaCallbacks) {
for (Map.Entry<String, GenericElementListener<? extends Nonza>> entry : filterAndListeners.entrySet()) {
String filterKey = entry.getKey();
NonzaCallback installedCallback = connection.nonzaCallbacks.get(filterKey);
if (equals(installedCallback)) {
connection.nonzaCallbacks.remove(filterKey);
}
}
}
}

protected void install() {
if (filterAndListeners.isEmpty()) {
return;
}

synchronized (connection.nonzaCallbacks) {
for (String key : filterAndListeners.keySet()) {
connection.nonzaCallbacks.put(key, this);
}
}
}

private static final class NonzaResponseCallback<SN extends Nonza, FN extends Nonza> extends NonzaCallback {

private SN successNonza;
private FN failedNonza;

private NonzaResponseCallback(Class<? extends SN> successNonzaClass, Class<? extends FN> failedNonzaClass,
Builder builder) {
super(builder);

final String successNonzaKey = XmppElementUtil.getKeyFor(successNonzaClass);
final String failedNonzaKey = XmppElementUtil.getKeyFor(failedNonzaClass);

final GenericElementListener<SN> successListener = new GenericElementListener<SN>(successNonzaClass) {
@Override
public void process(SN successNonza) {
NonzaResponseCallback.this.successNonza = successNonza;
notifyResponse();
}
};

final GenericElementListener<FN> failedListener = new GenericElementListener<FN>(failedNonzaClass) {
@Override
public void process(FN failedNonza) {
NonzaResponseCallback.this.failedNonza = failedNonza;
notifyResponse();
}
};

filterAndListeners.put(successNonzaKey, successListener);
filterAndListeners.put(failedNonzaKey, failedListener);

install();
}

private void notifyResponse() {
synchronized (this) {
notifyAll();
}
}

private boolean hasReceivedSuccessOrFailedNonza() {
return successNonza != null || failedNonza != null;
}

private SN waitForResponse() throws NoResponseException, InterruptedException, FailedNonzaException {
final long deadline = System.currentTimeMillis() + connection.getReplyTimeout();
synchronized (this) {
while (!hasReceivedSuccessOrFailedNonza()) {
final long now = System.currentTimeMillis();
if (now >= deadline) break;
wait(deadline - now);
}
}

if (!hasReceivedSuccessOrFailedNonza()) {
throw NoResponseException.newWith(connection, "Nonza Listener");
}

if (failedNonza != null) {
throw new XMPPException.FailedNonzaException(failedNonza);
}

assert successNonza != null;
return successNonza;
}
}

public static final class Builder {
private final AbstractXMPPConnection connection;

private Map<String, GenericElementListener<? extends Nonza>> filterAndListeners = new HashMap<>();

Builder(AbstractXMPPConnection connection) {
this.connection = connection;
}

public <N extends Nonza> Builder listenFor(Class<? extends N> nonza, GenericElementListener<? extends N> nonzaListener) {
String key = XmppElementUtil.getKeyFor(nonza);
filterAndListeners.put(key, nonzaListener);
return this;
}

public NonzaCallback install() {
return new NonzaCallback(this);
}
}

static <SN extends Nonza, FN extends Nonza> SN sendAndWaitForResponse(NonzaCallback.Builder builder, Nonza nonza, Class<SN> successNonzaClass,
Class<FN> failedNonzaClass)
throws NoResponseException, NotConnectedException, InterruptedException, FailedNonzaException {
NonzaResponseCallback<SN, FN> nonzaCallback = new NonzaResponseCallback<>(successNonzaClass,
failedNonzaClass, builder);

SN successNonza;
try {
nonzaCallback.connection.sendNonza(nonza);
successNonza = nonzaCallback.waitForResponse();
}
finally {
nonzaCallback.cancel();
}

return successNonza;
}
}

+ 4
- 1
smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java View File

@@ -180,13 +180,14 @@ public final class SASLAuthentication {
* @param password the password to send to the server.
* @param authzid the authorization identifier (typically null).
* @param sslSession the optional SSL/TLS session (if one was established)
* @return the used SASLMechanism.
* @throws XMPPErrorException
* @throws SASLErrorException
* @throws IOException
* @throws SmackException
* @throws InterruptedException
*/
public void authenticate(String username, String password, EntityBareJid authzid, SSLSession sslSession)
public SASLMechanism authenticate(String username, String password, EntityBareJid authzid, SSLSession sslSession)
throws XMPPErrorException, SASLErrorException, IOException,
SmackException, InterruptedException {
currentMechanism = selectMechanism(authzid);
@@ -223,6 +224,8 @@ public final class SASLAuthentication {
if (!authenticationSuccessful) {
throw NoResponseException.newWith(connection, "successful SASL authentication");
}

return currentMechanism;
}

/**


+ 66
- 0
smack-core/src/main/java/org/jivesoftware/smack/ScheduledAction.java View File

@@ -0,0 +1,66 @@
/**
*
* Copyright 2018 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;

import java.util.Date;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

public class ScheduledAction implements Delayed {

final Runnable action;
final Date releaseTime;
final SmackReactor smackReactor;

ScheduledAction(Runnable action, Date releaseTime, SmackReactor smackReactor) {
this.action = action;
this.releaseTime = releaseTime;
this.smackReactor = smackReactor;
}

public void cancel() {
smackReactor.cancel(this);
}

public boolean isDue() {
Date now = new Date();
return now.after(releaseTime);
}

public long getTimeToDueMillis() {
long now = System.currentTimeMillis();
return releaseTime.getTime() - now;
}

@Override
public int compareTo(Delayed otherDelayed) {
if (this == otherDelayed) {
return 0;
}

long thisDelay = getDelay(TimeUnit.MILLISECONDS);
long otherDelay = otherDelayed.getDelay(TimeUnit.MILLISECONDS);

return Long.compare(thisDelay, otherDelay);
}

@Override
public long getDelay(TimeUnit unit) {
long delayInMillis = getTimeToDueMillis();
return unit.convert(delayInMillis, TimeUnit.MILLISECONDS);
}
}

+ 24
- 2
smack-core/src/main/java/org/jivesoftware/smack/SmackException.java View File

@@ -94,12 +94,19 @@ public class SmackException extends Exception {
}

public static NoResponseException newWith(XMPPConnection connection,
StanzaCollector collector) {
return newWith(connection, collector.getStanzaFilter());
StanzaCollector collector, boolean stanzaCollectorCancelled) {
return newWith(connection, collector.getStanzaFilter(), stanzaCollectorCancelled);
}

public static NoResponseException newWith(XMPPConnection connection, StanzaFilter filter) {
return newWith(connection, filter, false);
}

public static NoResponseException newWith(XMPPConnection connection, StanzaFilter filter, boolean stanzaCollectorCancelled) {
final StringBuilder sb = getWaitingFor(connection);
if (stanzaCollectorCancelled) {
sb.append(" StanzaCollector has been cancelled.");
}
sb.append(" Waited for response using: ");
if (filter != null) {
sb.append(filter.toString());
@@ -182,6 +189,12 @@ public class SmackException extends Exception {
super("The connection " + connection
+ " is no longer connected while waiting for response with " + stanzaFilter);
}

public NotConnectedException(XMPPConnection connection, StanzaFilter stanzaFilter,
Exception connectionException) {
super("The connection " + connection + " is no longer connected while waiting for response with "
+ stanzaFilter + " because of " + connectionException, connectionException);
}
}

public static class IllegalStateChangeException extends SmackException {
@@ -283,6 +296,15 @@ public class SmackException extends Exception {
}
}

public static class ConnectionUnexpectedTerminatedException extends SmackException {

private static final long serialVersionUID = 1L;

public ConnectionUnexpectedTerminatedException(Throwable wrappedThrowable) {
super(wrappedThrowable);
}
}

public static class FeatureNotSupportedException extends SmackException {

/**


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

@@ -25,13 +25,19 @@ import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.jivesoftware.smack.compress.provider.CompressedProvider;
import org.jivesoftware.smack.compress.provider.FailureProvider;
import org.jivesoftware.smack.compression.Java7ZlibInputOutputStream;
import org.jivesoftware.smack.compression.XmppCompressionManager;
import org.jivesoftware.smack.compression.zlib.ZlibXmppCompressionFactory;
import org.jivesoftware.smack.initializer.SmackInitializer;
import org.jivesoftware.smack.packet.Bind;
import org.jivesoftware.smack.packet.Message.Body;
import org.jivesoftware.smack.provider.BindIQProvider;
import org.jivesoftware.smack.provider.BodyElementProvider;
import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smack.provider.TlsFailureProvider;
import org.jivesoftware.smack.provider.TlsProceedProvider;
import org.jivesoftware.smack.sasl.core.SASLAnonymous;
import org.jivesoftware.smack.sasl.core.SASLXOauth2Mechanism;
import org.jivesoftware.smack.sasl.core.SCRAMSHA1Mechanism;
@@ -97,6 +103,8 @@ public final class SmackInitialization {
// Add the Java7 compression handler first, since it's preferred
SmackConfiguration.compressionHandlers.add(new Java7ZlibInputOutputStream());

XmppCompressionManager.registerXmppCompressionFactory(ZlibXmppCompressionFactory.INSTANCE);

// Use try block since we may not have permission to get a system
// property (for example, when an applet).
try {
@@ -118,6 +126,11 @@ public final class SmackInitialization {
ProviderManager.addIQProvider(Bind.ELEMENT, Bind.NAMESPACE, new BindIQProvider());
ProviderManager.addExtensionProvider(Body.ELEMENT, Body.NAMESPACE, new BodyElementProvider());

ProviderManager.addNonzaProvider(TlsProceedProvider.INSTANCE);
ProviderManager.addNonzaProvider(TlsFailureProvider.INSTANCE);
ProviderManager.addNonzaProvider(CompressedProvider.INSTANCE);
ProviderManager.addNonzaProvider(FailureProvider.INSTANCE);

SmackConfiguration.smackInitialized = true;
}



+ 440
- 0
smack-core/src/main/java/org/jivesoftware/smack/SmackReactor.java View File

@@ -0,0 +1,440 @@
/**
*
* Copyright 2018-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.
* 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;

import java.io.IOException;
import java.lang.ref.WeakReference;
import java.nio.channels.CancelledKeyException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* The SmackReactor for non-blocking I/O.
* <p>
* Highlights include:
* <ul>
* <li>Multiple reactor threads</li>
* <li>Scheduled actions</li>
* </ul>
*
* <pre>
*
* ) ) )
* ( ( (
* ) ) )
* (~~~~~~~~~)
* | Smack |
* |Reactor|
* I _._
* I /' `\
* I | |
* f | |~~~~~~~~~~~~~~|
* .' | | # # # # |
* '______|___|___________###|
* </pre>
*/
public class SmackReactor {

private static final Logger LOGGER = Logger.getLogger(SmackReactor.class.getName());

private static final int DEFAULT_REACTOR_THREAD_COUNT = 2;

private static final int PENDING_SET_INTEREST_OPS_MAX_BATCH_SIZE = 1024;

private static SmackReactor INSTANCE;

static synchronized SmackReactor getInstance() {
if (INSTANCE == null) {
INSTANCE = new SmackReactor("DefaultReactor");
}
return INSTANCE;
}

private final Selector selector;
private final String reactorName;

private final List<Reactor> reactorThreads = Collections.synchronizedList(new ArrayList<>());

private final DelayQueue<ScheduledAction> scheduledActions = new DelayQueue<>();

private final Lock registrationLock = new ReentrantLock();

/**
* The semaphore protecting the handling of the actions. Note that it is
* initialized with -1, which basically means that one thread will always do I/O using
* select().
*/</