Migrate markdown documentation to javadoc

While markdown is easier to write, Smack's markdown documentation was
never tightly coupled with the source. For example, the markdown
documentation never provided links to the actual Java classes and
methods. This poses the risk that the documentation and the code
diverge over time. Furthermore, javadoc is constantly improving (for
example @snippet annotations) and I expect that one will be able to
write javadoc in markdown.

Fixes SMACK-928.
This commit is contained in:
Florian Schmaus 2023-02-03 09:36:54 +01:00
parent f65cf45b5c
commit c9a9982cef
101 changed files with 4441 additions and 5754 deletions

163
DEVELOPING.md Normal file
View File

@ -0,0 +1,163 @@
# Building Smack
## Linux
Building Smack is as simple as
```
git clone git@github.com:igniterealtime/Smack.git
cd Smack
gradle assemble
```
## Mac
Smack requires a case-sensitive file system in order to build. Unfortunately, the macOS operating system is case-insensitive by default.
To get around this, you can create a case-sensitive disk image to work from.
1. Launch Disk Utility (Applications > Utilities)
2. Click the +, or go to Edit > Add APFS Volume
3. Give it a name, e.g. "Smack"
4. Change the format to "APFS (Case-sensitive)"
5. Click Add
It'll auto-mount into /Volumes, e.g. /Volumes/Smack
```bash
cd /Volumes/Smack
git clone git@github.com:igniterealtime/Smack.git
cd Smack
gradle assemble
```
## Windows
Smack requires a case-sensitive file system in order to build. Unfortunately, Windows NTFS is case-insensitive by default.
To get around this, you can set specific folders as case-sensitive (requires Windows 10 v1803 or higher).
In an Administrator console:
```batch
fsutil.exe file SetCaseSensitiveInfo C:\git\Smack enable
cd \git\Smack
git clone git@github.com:igniterealtime/Smack.git
cd Smack
gradle assemble
```
# IDE Config
### Eclipse
Import IDE settings from `./resources/eclipse/` to configure proper ordering of imports and correct formatting that should pass the CheckStyle rules.
### IntelliJ IDEA
Import Java Code Style settings from `./resources/intellij/smack_formatter.xml` to configure import optimisation and code formatting to pass the CheckStyle rules when building or submitting PRs.
_We've noticed, at time of writing, that IntelliJ often requires a restart when applying new rules - no amount of OK/Apply will do the trick._
# Smack Providers
Providers are responsible for parsing the XMPP XML stream into new Java objects.
## Provider Design
Assume you want to parse the following stanza extension element
```xml
<myExtension attrFoo='fourthyTwo'>
<myElement>Foo is greater then Bar</myElement>
<myInfo alpha='true' delta='-1337'/>
</myExtension>
```
then the related provider would look like this
```java
public MyExtension parse(XmlPullParser parser, int initialDepth) {
MyElement myElement = null;
MyInfo myInfo = null;
String attrFoo = parser.getAttributeValue("", "attrFoo");
// Main parsing loop, use a loop label instead of "boolean done"
outerloop: while(true) {
// Make sure to have already parse all attributes of the outermost element,
// i.e. 'attrFoo' of 'myExtension' in this example. Then advance the parser
XmlPullParser.Event event = parser.next();
// Use switch/case of int instead of a if/else-if cascade
switch (event) {
case START_ELEMENT:
// Determine the name of the element which start tag we are seeing
String name = parser.getName();
// We can use switch/case of Strings since Java7, make use of its advantages
// and collect the values of the sub elements. If the sub elements are more
// complex then those of this example, consider creating extra *private static*
// parsing methods for them.
switch(name) {
case "myElement":
// You should only use XmlPullParser.nextText() when the element is
// required to have a text.
myElement = new MyElement(parser.nextText());
break;
case "myInfo";
// Use ParserUtils to parse Java primitives
boolenan alpha = ParserUtils.getBooleanAttribute(parser, "alpha");
int delta = ParserUtils.getIntegerAttribute(parser, "delta");
myInfo = new MyInfo(alpha, delta);
break;
}
break;
case END_ELEMENT:
// The abort condition with the break labeled loop statement
if (parser.getDepth() == initialDepth) {
break outerloop;
}
break;
default:
// Catch all for incomplete switch (MissingCasesInEnumSwitch) statement.
break;
}
}
// Create the actual class at the very end, design the classes as immutable as possible
return new MyExtension(attrFoo, myElement, myInfo);
}
```
## Common Pitfalls
Use a `long` instead of `int` when the XML schema says `xs:unsignedInt`, because Java's `int` range is to small for this XML numeric data type.
# Stanzas
## General Rules
All classes which subclass `TopLevelStreamElement` and `ExtensionElement` must either
1. be immutable (and ideally provide a Builder)
2. implement `TypedCloneable`
and must be `Serializable`.
The reason that it must be either 1. or 2. is that it makes no sense to clone an inmutable instance.
The preferred option is 1.
Note that there is legacy code in Smack which does not follow these rules. Patches are welcome.
## ExtensionElement
Extension elements are XML elements that are used in various parts and levels of stanzas.
## The static `from(Stanza)` Method
Every ExtensionElement class must have a static `from()` method that retrieves that extension for a given Stanza (if any).
Sample Code
```java
public static RSMSet from(Stanza) {
return packet.getExtension(ELEMENT, NAMESPACE);
}
```
Sometimes certain ExtensionElement's are only found in one stanza type, in that case, specify the parameter type. For example `public static CarbonExtension getFrom(Message)`.

View File

@ -1 +0,0 @@
index.md

View File

@ -1,35 +0,0 @@
Smack's Modular Connection Architecture
======================================
[Back](index.md)
**Note: Everything related to the modular connection architecture is currently considered experimental and should not be used in production. Use the mature `XMPPTCPConnection` if you do not feel adventurous.
Smack's modular connection architecture allows to extend a XMPP c2s (client-to-server) connection with additional functionality by adding modules.
Those modules extend the Finite State Machine (FSM) within the `ModularXmppClientToServerConnection` with new states.
Connection modules can either be
- Transports
- Extensions
Transports bind the XMPP XML stream to an underlying transport like TCP, WebSockets, BOSH, and allow for the different particularities of transports like DirectTLS ([XEP-0368](https://xmpp.org/extensions/xep-0368.html)).
This eventually means that a single transport module can implement multiple transport mechanisms.
For example the TCP transport module implements the RFC6120 TCP and the XEP-0368 direct TLS TCP transport bindings.
Extensions allow for a richer functionality of the connection. Those include
- Compression
- zlib ([XEP-0138](https://xmpp.org/extensions/xep-0138.html))
- [Efficient XML Interchange (EXI)](https://www.w3.org/TR/exi/)
- Instant Stream Resumption ([XEP-0397](https://xmpp.org/extensions/xep-0397.html)
- Bind2
- Stream Management
Note that not all extensions work with every transport.
For example compression only works with TCP-based transport bindings.
Connection modules are plugged into the the modular connection via their constructor. and they usually declare backwards edges to some common, generic connection state of the FSM.
Modules and states always have an accompanying *descriptor* type.
`ModuleDescriptor` and `StateDescriptor` exist without an connection instance.
They describe the module and state metadata, while their modules and states are instanciated once a modular connection is instanciated.

View File

@ -1,58 +0,0 @@
Smack: XMPPConnection Management
================================
[Back](index.md)
Creating a Connection
---------------------
The `org.jivesoftware.smack.XMPPConnection` interface manages your connection to
an XMPP server. The default implementation is the
`org.jivesoftware.smack.tcp.XMPPTCPConnection` class. The class contains three constructors. The simplest, `XMPPTCPConnection(CharSequence, String, String)` takes the username, password, and server name you'd like
to connect to as arguments. All default connection settings will be used:
* A DNS SRV lookup will be performed to find the exact address and port (typically 5222) that the server resides at.
* The maximum security possible will be negotiated with the server, including TLS encryption, but the connection will fall back to lower security settings if necessary.
* The XMPP resource name "Smack" will be used for the connection.
Alternatively, you can use the `XMPPTCPConnection(ConnectionConfiguration)`
constructor to specify advanced connection settings. Some of these settings
include:
* Manually specify the server address and port of the server rather than using a DNS SRV lookup.
* Enable connection compression.
* Customize security settings, such as flagging the connection to require TLS encryption in order to connect.
* Specify a custom connection resource name such as "Work" or "Home". Every connection by a user to a server must have a unique resource name. For the user "jsmith@example.com", the full address with resource might be "jsmith@example.com/Smack". With unique resource names, a user can be logged into the server from multiple locations at once, or using multiple devices. The presence priority value used with each resource will determine which particular connection receives messages to the bare address ("jsmith@example.com" in our example).
Connect and Disconnect
----------------------
```
// Create the configuration for this new connection
XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder();
configBuilder.setUsernameAndPassword("username", "password");
configBuilder.setResource("SomeResource");
configBuilder.setXmppDomain("jabber.org");
AbstractXMPPConnection connection = new XMPPTCPConnection(configBuilder.build());
// Connect to the server
connection.connect();
// Log into the server
connection.login();
...
// Disconnect from the server
connection.disconnect();
```
By default Smack will try to reconnect the connection in case it was abruptly
disconnected. The reconnection manager will try to immediately
reconnect to the server and increase the delay between attempts as successive
reconnections keep failing._
In case you want to force a reconnection while the reconnection manager is
waiting for the next reconnection, you can just use _AbstractXMPPConnection#connect()_
and a new attempt will be made. If the manual attempt also failed then the
reconnection manager will still continue the reconnection job.
Copyright (C) Jive Software 2002-2008

View File

@ -1,62 +0,0 @@
Debugging with Smack
====================
[Back](index.md)
Smack includes two built-in debugging consoles that will let you track
all XML traffic between the client and server. A lite debugger and an
enhanced debugger contained in `smack-debug.jar`, and a console debugger in `smack-core.jar`.
Debugging mode can be enabled in two different ways:
1. Add the following line of code **before** creating new connections:
`SmackConfiguration.DEBUG = true;`
2. Set the Java system property `smack.debugEnabled` to true. The system property can be set on the command line such as:
`java -Dsmack.debugEnabled=true SomeApp `
If you wish to explicitly disable debug mode in your application, including
using the command-line parameter, add the following line to your application
before opening new connections:
`SmackConfiguration.DEBUG = false;`
Smack uses the following logic to decide the debugger console to use:
1. It will first try use the debugger class specified in the Java system property `smack.debuggerClass`. If you need to develop your own debugger, implement the `SmackDebugger` interface and then set the system property on the command line such as:
`java -Dsmack.debuggerClass=my.company.com.MyDebugger SomeApp `
2. If step 1 fails then Smack will try to use the enhanced debugger. The file `smack-debug.jar` contains the enhanced debugger. Therefore you will need to place the jar file in the classpath. For situations where space is an issue you may want to only deploy `smack-core.jar` in which case the enhanced and lite debugger won't be available, but only the console debugger.
3. The last option if the previous two steps fail is to use the console debugger. The console debugger is a very good option for situations where you need to have low memory footprint.
Enhanced Debugger
-----------------
![Full Debug Window](images/enhanceddebugger.png) When debugging mode is
enabled, a debug window will appear containing tabs for each new created
connection. The window will contain the following information:
* XMPPConnection tabs -- each tab shows debugging information related to the connection.
* Smack info tab -- shows information about Smack (e.g. Smack version, installed components, etc.). The connection tab will contain the following information:
* All Stanzas -- shows sent and received packets information parsed by Smack.
* Raw Sent Stanzas -- raw XML traffic generated by Smack and sent to the server.
* Raw Received Stanzas -- raw XML traffic sent by the server to the client.
* Ad-hoc message -- allows to send ad-hoc packets of any type.
* Information -- shows connection state and statistics.
Lite Debugger
-------------
![Lite Debug Window](images/debugwindow.gif) When debugging mode is enabled, a
debug window will appear when each new connection is created. The window will
contain the following information:
* Client Traffic (red text) -- raw XML traffic generated by Smack and sent to the server.
* Server Traffic (blue text) -- raw XML traffic sent by the server to the client.
* Interpreted Stanzas (green text) -- shows XML packets from the server as parsed by Smack. Right click on any of the panes to bring up a menu with the choices to copy of the contents to the system clipboard or to clear the contents of the pane.
Copyright (C) Jive Software 2002-2008

View File

@ -1,63 +0,0 @@
Building Smack
==============
Linux
-----
Building Smack is as simple as
```
git clone git@github.com:igniterealtime/Smack.git
cd Smack
gradle assemble
```
Mac
---
Smack requires a case-sensitive file system in order to build. Unfortunately, the macOS operating system is case-insensitive by default.
To get around this, you can create a case-sensitive disk image to work from.
1. Launch Disk Utility (Applications > Utilities)
2. Click the +, or go to Edit > Add APFS Volume
3. Give it a name, e.g. "Smack"
4. Change the format to "APFS (Case-sensitive)"
5. Click Add
It'll auto-mount into /Volumes, e.g. /Volumes/Smack
```bash
cd /Volumes/Smack
git clone git@github.com:igniterealtime/Smack.git
cd Smack
gradle assemble
```
Windows
-------
Smack requires a case-sensitive file system in order to build. Unfortunately, Windows NTFS is case-insensitive by default.
To get around this, you can set specific folders as case-sensitive (requires Windows 10 v1803 or higher).
In an Administrator console:
```batch
fsutil.exe file SetCaseSensitiveInfo C:\git\Smack enable
cd \git\Smack
git clone git@github.com:igniterealtime/Smack.git
cd Smack
gradle assemble
```
IDE Config
----------
### Eclipse
Import IDE settings from `./resources/eclipse/` to configure proper ordering of imports and correct formatting that should pass the CheckStyle rules.
### IntelliJ IDEA
Import Java Code Style settings from `./resources/intellij/smack_formatter.xml` to configure import optimisation and code formatting to pass the CheckStyle rules when building or submitting PRs.
_We've noticed, at time of writing, that IntelliJ often requires a restart when applying new rules - no amount of OK/Apply will do the trick._

View File

@ -1,209 +0,0 @@
Smack's Integration Test Framework
==================================
Introduction
------------
Smack's Integration Test Framework is used to run a set of tests against a real XMPP service.
The framework discovers on start-up the available tests by reflection.
Quickstart
----------
You can run the framework against an XMPP service with
```bash
$ gradle integrationTest -Dsinttest.service=my.xmppservice.org
```
Note that the service needs to have In-Band Registration (IBR) enabled.
A better alternative to IBR is using XEP-0133: Service Administration
to create the throw away accounts used by the integration test
framework. Simply use
```bash
$ gradle integrationTest -Dsinttest.service=my.xmppservice.org \
-Dsinttest.adminAccountUsername=admin \
-Dsinttest.adminAccountPassword=aeR0Wuub
```
to run Smack's integration test framework against `my.xmppservice.org`
with an admin account named `admin` and `aeR0Wuub` as password.
Configuration
-------------
The framework is configured with a standard Java properties file.
This file simply contains key/value pairs, which are separated by an equals sign ("=").
The most important configuration value is the `service` value, it's also the only required setting.
The file properties can be overridden with Java system properties.
The name of a system property that is used by the framework needs to be prefixed with `sinttest.` (*S*mack *Int*egration *Test* Framework).
For example the `service` property becomes `sinttest.service`.
### Minimal example **properties** file
```bash
service=example.org
```
### Another example **properties** file
```bash
service=example.org
serviceTlsPin=CERTSHA256:2F:92:C9:4D:30:58:E1:05:21:9A:57:59:5F:6E:25:9A:0F:BF:FF:64:1A:C3:4B:EC:06:7D:4A:6F:0A:D5:21:85
debugger=console
```
### Framework properties
| Name | Description |
|----------------------|-----------------------------------------------------------------------------|
| service | XMPP service to run the tests on |
| serviceTlsPin | TLS Pin (used by [java-pinning](https://github.com/Flowdalic/java-pinning)) |
| securityMode | Either 'required' or 'disabled' |
| replyTimeout | In milliseconds |
| adminAccountUsername | Username of the XEP-0133 Admin account |
| adminAccountPassword | Password of the XEP-0133 Admin account |
| accountOneUsername | Username of the first XMPP account |
| accountOnePassword | Password of the first XMPP account |
| accountTwoUsername | Username of the second XMPP account |
| accountTwoPassword | Password of the second XMPP account |
| accountThreeUsername | Username of the third XMPP account |
| accountThreePassword | Password of the third XMPP account |
| debugger | 'console' for console debugger, 'enhanced' for the enhanced debugger |
| enabledTests | List of enabled tests |
| disabledTests | List of disabled tests |
| defaultConnection | Nickname of the default connection |
| enabledConnections | List of enabled connection's nicknames |
| disabledConnections | List of disabled connection's nicknames |
| testPackages | List of packages with tests |
| verbose | If `true` set output to verbose |
| dnsResolver | One of 'minidns', 'javax' or 'dnsjava'. Defaults to 'minidns'. |
### Where to place the properties file
The framework will first load the properties file from `~/.config/smack-integration-test/properties`
### Running selected tests only
Using `enabledTests` is is possible to run only selected tests. The
tests can be selected on a per class base or by specifying concrete
test methods. In the latter case, the methods must be qualified by a
(simple) class name.
For example:
```bash
$ gradle integrationTest -Dsinttest.enabledTests=SoftwareInfoIntegrationTest.test
```
will only run the `test()` method of `SoftwareInfoIntegrationTest`, whereas
```bash
$ gradle integrationTest -Dsinttest.enabledTests=SoftwareInfoIntegrationTest
```
would run all tests defined in the `SoftwareInfoIntegrationTest` class.
Overview of the components
--------------------------
Package `org.igniterealtime.smack.inttest`
### `SmackIntegrationTestFramework`
Contains `public static void main` method, i.e. the entry point for the framework.
Here the available integration tests are discovered by means of reflection, the configuration is read and a `IntegrationTestEnvironment` instance created, which includes the XMPPConnections.
### `AbstractSmackIntegrationTest`
The base class that integration tests need to subclass.
### `AbstractSmackLowLevelIntegrationTest`
Allows low level integration test, i.e. every test method will have its own exclusive XMPPTCPConnection instances.
### `AbstractSmackSpecificLowLevelIntegrationTest`
Operates, like `AbstractSmackLowLevelIntegrationTest` on its own `XMPPConnection` instances, but is limited to a particular type of `XMPPConnection`.
### `IntegrationTestEnvironment`
The environment, e.g. the `XMPPConnections` provided to the integration tests by the framework. Note that for convenience `AbstractSmackIntegrationTest` contains some of those as protected members.
### `SmackIntegrationTest`
An annotation that needs to be added to all methods that represent a single integration test.
Annotated integration test methods must not take any arguments (i.e. their parameter count is 0), and should return void as it's not evaluated in any way.
The methods are supposed to throw an exception if their integration test fails.
### `TestNotPossibleException`
Can be thrown by test methods or constructors to signal that their test is not possible, e.g. because the service does not support the required feature.
Running the integration tests
-----------------------------
Smack's Gradle build system is configured with a special task called `integrationTest`, which means you can run the tests simply with
```bash
$ gradle integrationTest -Dsinttest.service=my.xmppservice.org
```
If one of `accountOneUsername`, `accountOnePassword`, `accountTwoUsername` or `accountTwoPassword` is not configured, then the framework will automatically create the accounts on the service. Of course this requires account registration (IBR) to be enabled.
If the accounts got created automatically by the framework, then they will also be deleted at the end of the test.
Implementing Integration Tests
------------------------------
Create a new class which extends `AbstractSmackIntegrationTest`.
Every non-static method, including the constructor, of this class will have two XMPPConnections available to perform the integration tests with: `conOne` and `conTwo`.
You can use the constructor to check if the XMPP service does provide the required XMPP feature.
If it does not, simply throw a `TestNotPossibleException`.
Test methods must be `public`, take zero arguments i.e. declare no parameters and be annoated with `@SmackIntegrationTest`.
If the test method is not able to perform a test then it should throw a `TestNotPossibleException`.
### Rules for integration tests
Tests should not leave any traces on the service if they are finished, i.e. the service state at the end of the test must be equal to the state of the beginning.
It must be possible to run the tests in parallel.
### Why are there two mechanisms to signal that the test is not possible?
Because the XMPP service may provide a component that is required to perform a certain integration test, but that component may not support all features.
For example, the XMPP service may provides a PubSub (XEP-0060) component, but this component may not support all features of XEP-0060.
### Low-Level Integration Tests
Classes that implement low-level integration tests need to sublcass `AbstractSmackLowLevelIntegrationTest`.
The test methods can declare as many parameters as they need to, but every parameter must be of type `XMPPTCPConnection`.
The framework will automatically create, register and login the connections.
After the test is finished, the connections will be unregistered with the XMPP service and terminated.
Debugging Integration Tests
------------------------------
A test, like any other code, may not be perfect on the first attempt, and you may require more information in order to ascertain quite what's wrong.
### Smack Debugger options
As listed in the main Smack [Debugging](../debugging.md) doc, there are two built-in debuggers that could surface you more information. Using the 'enhanced' debugger config option listed above, you'll get the Smack Debug Window launching when your tests launch, and you'll get a stanza-by-stanza account of what happened on each connection, hopefully enough to diagnose what went wrong.
### Debugging in the IDE
If the output isn't enough, you may need to debug and inspect running code within the IDE. Depending on the IDE, in order to get execution to pause at your breakpoints, you may need to switch your configuration. Instead of running `gradle integrationTest`, instead run the `SmackIntegrationTestFramework` class directly with the same command-line options.
Running your own integration tests
----------------------------------
The framework can be used to run your own tests residing outside of the framework's default package scope.
Simply set the `testPackages` property to a comma separated list of package names where the framework should look for integration tests.
Example:
```bash
$ gradle integrationTest -Dsinttest.service=my.xmppserivce.org -Dsinttest.testPackages=org.mypackage,org.otherpackage
```

View File

@ -1,75 +0,0 @@
Smack Providers
===============
Providers are responsible for parsing the XMPP XML stream into new Java objects.
Provider Design
---------------
Assume you want to parse the following stanza extension element
```xml
<myExtension attrFoo='fourthyTwo'>
<myElement>Foo is greater then Bar</myElement>
<myInfo alpha='true' delta='-1337'/>
</myExtension>
```
then the related provider would look like this
```java
public MyExtension parse(XmlPullParser parser, int initialDepth) {
MyElement myElement = null;
MyInfo myInfo = null;
String attrFoo = parser.getAttributeValue("", "attrFoo");
// Main parsing loop, use a loop label instead of "boolean done"
outerloop: while(true) {
// Make sure to have already parse all attributes of the outermost element,
// i.e. 'attrFoo' of 'myExtension' in this example. Then advance the parser
XmlPullParser.Event event = parser.next();
// Use switch/case of int instead of a if/else-if cascade
switch (event) {
case START_ELEMENT:
// Determine the name of the element which start tag we are seeing
String name = parser.getName();
// We can use switch/case of Strings since Java7, make use of its advantages
// and collect the values of the sub elements. If the sub elements are more
// complex then those of this example, consider creating extra *private static*
// parsing methods for them.
switch(name) {
case "myElement":
// You should only use XmlPullParser.nextText() when the element is
// required to have a text.
myElement = new MyElement(parser.nextText());
break;
case "myInfo";
// Use ParserUtils to parse Java primitives
boolenan alpha = ParserUtils.getBooleanAttribute(parser, "alpha");
int delta = ParserUtils.getIntegerAttribute(parser, "delta");
myInfo = new MyInfo(alpha, delta);
break;
}
break;
case END_ELEMENT:
// The abort condition with the break labeled loop statement
if (parser.getDepth() == initialDepth) {
break outerloop;
}
break;
default:
// Catch all for incomplete switch (MissingCasesInEnumSwitch) statement.
break;
}
}
// Create the actual class at the very end, design the classes as immutable as possible
return new MyExtension(attrFoo, myElement, myInfo);
}
```
Common Pitfalls
---------------
Use a `long` instead of `int` when the XML schema says `xs:unsignedInt`, because Java's `int` range is to small for this XML numeric data type.

View File

@ -1,33 +0,0 @@
General Rules
=============
All classes which subclass `TopLevelStreamElement` and `ExtensionElement` must either
1. be immutable (and ideally provide a Builder)
2. implement `TypedCloneable`
and must be `Serializable`.
The reason that it must be either 1. or 2. is that it makes no sense to clone an inmutable instance.
The preferred option is 1.
Note that there is legacy code in Smack which does not follow these rules. Patches are welcome.
ExtensionElement
================
Extension elements are XML elements that are used in various parts and levels of stanzas.
The static `from(Stanza)` Method
--------------------------------
Every ExtensionElement class must have a static `from()` method that retrieves that extension for a given Stanza (if any).
Sample Code
```java
public static RSMSet from(Stanza) {
return packet.getExtension(ELEMENT, NAMESPACE);
}
```
Sometimes certain ExtensionElement's are only found in one stanza type, in that case, specify the parameter type. For example `public static CarbonExtension getFrom(Message)`.

View File

@ -1,75 +0,0 @@
DNSSEC and DANE
===============
[Back](index.md)
**DNSSEC and DANE support in Smack and MiniDNS is still in its
infancy. It should be considered experimental and not ready for
production use at this time.** We would like to see more thorough
testing and review by the security community. If you can help, then
please do not hesitate to contact us.
About
-----
DNSSEC ([RFC 4033](https://tools.ietf.org/html/rfc4033) and others)
authenticates DNS answers, positive and negative ones. This means that
if a DNS response secured by DNSSEC turns out to be authentic, then
you can be sure that the domain either exists, and that the returned
resource records (RRs) are the ones the domain owner authorized, or
that the domain does not exists and that nobody tried to fake its non
existence.
The tricky part is that an application using DNSSEC can not determine
whether a domain uses DNSSEC, does not use DNSSEC or if someone
downgraded your DNS query using DNSSEC to a response without DNSSEC.
[DANE](https://tools.ietf.org/html/rfc6698) allows the verification of
a TLS certificate with information stored in the DNS system and
secured by DNSSEC. Thus DANE requires DNSSEC.
Prerequisites
-------------
From the three DNS resolver providers (MiniDNS, javax, dnsjava)
supported by Smack only [MiniDNS](https://github.com/rtreffer/minidns)
currently supports DNSSEC. MiniDNS is the default resolver when
smack-android is used. For other configurations, make sure to add
smack-resolver-minidns to your dependencies and call
`MiniDnsResolver.setup()` prior using Smack (e.g. in a `static {}`
code block).
DNSSEC API
----------
Smack's DNSSEC API is very simple: Just use
`ConnectionConfiguration.Builder..setDnssecMode(DnssecMode)` to enable
DNSSEC. `DnssecMode` can be one of
- `disabled`
- `needsDnssec`
- `needsDnssecAndDane`
The default is `disabled`.
If `needsDnssec` is used, then Smack will only connect if the DNS
results required to determine a host for the XMPP domain could be
verified using DNSSEC.
If `needsDnssecAndDane` then DANE will be used to verify the XMPP
service's TLS certificate if STARTTLS is used. Note that you may want
to configure
`ConnectionConfiguration.Builder.setSecurityMode(SecurityMode.required)`
if you use this DNSSEC mode setting.
Best practices
--------------
We recommend that applications using Smack's DNSSEC API do not ask the
user if DNSSEC is avaialble. Instead they should check for DNSSEC
suport on every connection attempt. Once DNSSEC support has been
discovered, the application should use the `needsDnssec` mode for all
future connection attempts. The same scheme can be applied when using
DANE. This approach is similar to the scheme established by
to
["HTTP Strict Transport Security" (HSTS, RFC 6797)](https://tools.ietf.org/html/rfc6797).

View File

@ -1,76 +0,0 @@
Blocking Command
================
[Back](index.md)
Allows one to manage communications blocking.
* Check push notifications support
* Get blocking list
* Block contact
* Unblock contact
* Unblock all
* Check if a message has a blocked error
**XEP related:** [XEP-0191](http://xmpp.org/extensions/xep-0191.html)
Get an instance of Blocking Command Manager
-------------------------------------------
```
BlockingCommandManager blockingCommandManager = BlockingCommandManager.getInstanceFor(connection);
```
Check blocking command support
------------------------------
```
boolean isSupported = blockingCommandManager.isSupportedByServer();
```
Get block list
--------------
```
List<Jid> blockList = blockingCommandManager.getBlockList();
```
Block contact
-------------
```
blockingCommandManager.blockContacts(jids);
```
*jids* is a `java.util.List<Jid>`
Unblock contact
---------------
```
blockingCommandManager.unblockContacts(jids);
```
*jids* is a `java.util.List<Jid>`
Unblock all
-----------
```
blockingCommandManager.unblockAll();
```
Check if a message has a blocked error
--------------------------------------
```
BlockedErrorExtension.isInside(message));
```
*message* is a `Message`

View File

@ -1,49 +0,0 @@
Entity Capabilities
===================
[Back](index.md)
This section details the usage of Smacks implementation of Entity
Capabilities.
**XEP related:** [XEP-0115: Entity Capabilities](http://xmpp.org/extensions/xep-0115.html)
**Description**
Entity Capabilities is an XMPP Protocol extension, which, in order to minimize
network impact, caches the capabilities of XMPP entities. Those capabilities
are determined with the help of the Service Discovery Protocol
([XEP-0030](http://xmpp.org/extensions/xep-0030.html)).
**Usage**
Entity Capabilities work silently in the background when enabled. If the remote
XMPP entity does not support XEP-0115 but XEP-0030 then XEP-0030 mechanisms
are transparently used. You can enable or disable Entity Capabilities by using
_**EntityCapsManager**_.
The cache used by Smack for Entity Capabilities is non-persistent as default.
That is, the cache only uses memory. But it is also possible to set a
persistent Entity Capabilities cache, which is recommended.
**Examples**
Enable Entity Capabilities
```
// Get an instance of entity caps manager for the specified connection
EntityCapsManager mgr = EntityCapsManager.getInstanceFor(connection);
// Enable entity capabilities
mgr.enableEntityCaps();
```
Configure a persistent cache for Entity Capabilities
```
// Get an instance of entity caps manager for the specified connection
EntityCapsManager mgr = EntityCapsManager.getInstanceFor(connection);
// Create an cache, see smackx.entitycaps.cache for pre-defined cache implementations
EntityCapsPersistentCache cache = new SimpleDirectoryPersistentCache(new File("/foo/cachedir"));
// Set the cache
mgr.setPersistentCache(cache);
```

View File

@ -1,37 +0,0 @@
Consistent Colors
=================
[Back](index.md)
Since XMPP can be used on multiple platforms at the same time,
it might be a good idea to render given Strings like nicknames in the same
color on all platforms to provide a consistent user experience.
The utility class `ConsistentColor` allows the generation of colors to a given
string following the specification of [XEP-0392](https://xmpp.org/extensions/xep-0392.html).
## Usage
To generate a consistent color for a given string, call
```
float[] rgb = ConsistentColor.RGBFrom(input);
```
The resulting float array contains values for RGB in the range of 0 to 1.
## Color Deficiency Corrections
Some users might suffer from color vision deficiencies. To compensate those deficiencies,
the API allows for color correction. The color correction mode is a static value, which can be changed at any time.
To correct colors for users with red-green color deficiency use the following code:
```
ConsistentColor.activateRedGreenBlindnessCorrection();
```
For color correction for users with blue-blindness, call
```
ConsistentColor.activateBlueBlindnessCorrection();
```
To deactivate color vision deficiency correction, call
```
ConsistentColor.deactivateDeficiencyCorrection();
```

View File

@ -1,145 +0,0 @@
Data Forms
==========
[Back](index.md)
Allows the exchange of structured data between users and applications for common
tasks such as registration and searching using Forms.
* Create a Form to fill out
* Answer a Form
**XEP related:** [XEP-4](http://www.xmpp.org/extensions/xep-0004.html)
Create a Form to fill out
-------------------------
**Description**
An XMPP entity may need to gather data from another XMPP entity. Therefore,
the data-gathering entity will need to create a new Form, specify the fields
that will conform to the Form and finally send the Form to the data-providing
entity.
**Usage**
In order to create a Form to fill out use the _**Form**_'s constructor passing
the constant **DataForm.type.form** as the parameter. The next step is to create
the form fields and add them to the form. In order to create and customize a
_**FormField**_ use the _**FormField**_'s constructor specifying the variable
name of the field as the parameter. Then use **setType(FormField.Type type)** to set
the field's type (e.g. FormField.Type.hidden, FormField.Type.text_single).
Once we have the _**Form**_ instance and the _**FormFields**_, the last step is
to send **addField(FormField field)** for each field that we want to add to
the form.
Once the form to fill out is finished we will want to send it in a message.
Send **getDataFormToSend()** to the form and add the answer as an extension to
the message to send.
**Examples**
In this example we can see how to create and send a form to fill out:
```
// Create a new form to gather data
Form formToSend = new Form(DataForm.Type.form);
formToSend.setInstructions("Fill out this form to report your case.\nThe case will be created automatically.");
formToSend.setTitle("Case configurations");
// Add a hidden variable to the form
FormField field = new FormField("hidden_var");
field.setType(FormField.Type.hidden);
field.addValue("Some value for the hidden variable");
formToSend.addField(field);
// Add a fixed variable to the form
field = new FormField();
field.addValue("Section 1: Case description");
formToSend.addField(field);
// Add a text-single variable to the form
field = new FormField("name");
field.setLabel("Enter a name for the case");
field.setType(FormField.Type.text_single);
formToSend.addField(field);
// Add a text-multi variable to the form
field = new FormField("description");
field.setLabel("Enter a description");
field.setType(FormField.Type.text_multi);
formToSend.addField(field);
// Create a chat with "user2@host.com"
Chat chat = ChatManager.getInstanceFor(conn1).chatWith("user2@host.com" );
Message msg = new Message();
msg.setBody("To enter a case please fill out this form and send it back");
// Add the form to fill out to the message to send
msg.addExtension(formToSend.getDataFormToSend());
// Send the message with the form to fill out
chat.send(msg);
```
Answer a Form
-------------
**Description**
Under many situations an XMPP entity could receive a form to fill out. For
example, some hosts may require to fill out a form in order to register new
users. Smack lets the data-providing entity to complete the form in an easy
way and send it back to the data-gathering entity.
**Usage**
The form to fill out contains useful information that could be used for
rendering the form. But it cannot be used to actually complete it. Instead
it's necessary to create a new form based on the original form whose purpose
is to hold all the answers.
In order to create a new _**Form**_ to complete based on the original
_**Form**_ just send **createAnswerForm()** to the original _**Form**_. Once
you have a valid form that can be completed, all you have to do is
send **setAnswer(String variable, String value)** to the form where variable
is the variable of the _**FormField**_ that you want to answer and value is
the String representation of the answer. If the answer consists of several
values you could then use **setAnswer(String variable, List values)** where
values is a List of Strings.
Once the form has been completed we will want to send it back in a message.
Send **getDataFormToSend()** to the form and add the answer as an extension to
the message to send back.
**Examples**
In this example we can see how to retrieve a form to fill out, complete the
form and send it back:
```
// Get the message with the form to fill out
Chat chat2 = ChatManager.getInstanceFor(conn).addIncomingListener(
new IncomingChatMessageListener() {
@Override public void newIncomingMessage(EntityBareJid from, Message message, Chat chat) {
// Retrieve the form to fill out from the message
Form formToRespond = Form.getFormFrom(message);
// Obtain the form to send with the replies
Form completedForm = formToRespond.createAnswerForm();
// Add the answers to the form
completedForm.setAnswer("name", "Credit card number invalid");
completedForm.setAnswer("description", "The ATM says that my credit card number is invalid");
Message msg2 = new Message();
msg2.setBody("To enter a case please fill out this form and send it back");
// Add the completed form to the message to send back
msg2.addExtension(completedForm.getDataFormToSend());
// Send the message with the completed form
chat.send(msg2);
}
});
```

View File

@ -1,235 +0,0 @@
Service Discovery
=================
[Back](index.md)
The service discovery extension allows one to discover items and information about
XMPP entities. Follow these links to learn how to use this extension.
* Manage XMPP entity features
* Provide node information
* Discover items associated with an XMPP entity
* Discover information about an XMPP entity
* Publish publicly available items
**XEP related:** [XEP-30](http://www.xmpp.org/extensions/xep-0030.html)
Manage XMPP entity features
---------------------------
**Description**
Any XMPP entity may receive a discovery request and must answer with its
associated items or information. Therefore, your Smack client may receive a
discovery request that must respond to (i.e., if your client supports XHTML-
IM). This extension automatically responds to a discovery request with the
information that you previously configured.
**Usage**
In order to configure the supported features by your client you should first
obtain the ServiceDiscoveryManager associated with your XMPPConnection. To get
your ServiceDiscoveryManager send **getInstanceFor(connection)** to the class
_**ServiceDiscoveryManager**_ where connection is your XMPPConnection.
Once you have your ServiceDiscoveryManager you will be able to manage the
supported features. To register a new feature send **addFeature(feature)** to
your _**ServiceDiscoveryManager**_ where feature is a String that represents
the supported feature. To remove a supported feature send
**removeFeature(feature)** to your _**ServiceDiscoveryManager**_ where feature
is a String that represents the feature to remove.
**Examples**
In this example we can see how to add and remove supported features:
```
// Obtain the ServiceDiscoveryManager associated with my XMPP connection
ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection);
// Register that a new feature is supported by this XMPP entity
discoManager.addFeature(namespace1);
// Remove the specified feature from the supported features
discoManager.removeFeature(namespace2);
```
Provide node information
------------------------
**Description**
Your XMPP entity may receive a discovery request for items non-addressable as
a JID such as the MUC rooms where you are joined. In order to answer the
correct information it is necessary to configure the information providers
associated to the items/nodes within the Smack client.
**Usage**
In order to configure the associated nodes within the Smack client you will
need to create a NodeInformationProvider and register it with the
_**ServiceDiscoveryManager**_. To get your ServiceDiscoveryManager send
**getInstanceFor(connection)** to the class _**ServiceDiscoveryManager**_
where connection is your XMPPConnection.
Once you have your ServiceDiscoveryManager you will be able to register
information providers for the XMPP entity's nodes. To register a new node
information provider send **setNodeInformationProvider(String node,
NodeInformationProvider listener)** to your _**ServiceDiscoveryManager**_
where node is the item non-addressable as a JID and listener is the
_**NodeInformationProvider**_ to register. To unregister a
_**NodeInformationProvider**_ send **removeNodeInformationProvider(String
node)** to your _**ServiceDiscoveryManager**_ where node is the item non-
addressable as a JID whose information provider we want to unregister.
**Examples**
In this example we can see how to register a NodeInformationProvider with a
ServiceDiscoveryManager that will provide information concerning a node named
"http://jabber.org/protocol/muc#rooms":
```
// Set the NodeInformationProvider that will provide information about the
// joined rooms whenever a disco request is received
ServiceDiscoveryManager.getInstanceFor(connection).setNodeInformationProvider(
"http://jabber.org/protocol/muc#rooms",
new NodeInformationProvider() {
public List<DiscoverItems.Item> getNodeItems() {
MultiUserChatManager mucManager = MultiUserChatManager.getInstanceFor(connection);
List<DiscoverItems.Item> answer = new ArrayList<>();
Iterator<Jid> rooms = mucManager.getJoinedRooms().iterator();
while (rooms.hasNext()) {
answer.add(new DiscoverItems.Item(rooms.next()));
}
return answer;
}
public List<String> getNodeFeatures() {...}
public List<DiscoverInfo.Identity> getNodeIdentities() {...}
public List<ExtensionElement> getNodePacketExtensions() {...}
});
```
Discover items associated with an XMPP entity
---------------------------------------------
**Description**
In order to obtain information about a specific item you have to first
discover the items available in an XMPP entity.
**Usage**
Once you have your ServiceDiscoveryManager you will be able to discover items
associated with an XMPP entity. To discover the items of a given XMPP entity
send **discoverItems(entityID)** to your _**ServiceDiscoveryManager**_ where
entityID is the ID of the entity. The message **discoverItems(entityID)** will
answer an instance of _**DiscoverItems**_ that contains the discovered items.
**Examples**
In this example we can see how to discover the items associated with an online
catalog service:
```
// Obtain the ServiceDiscoveryManager associated with my XMPPConnection
ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection);
// Get the items of a given XMPP entity
// This example gets the items associated with online catalog service
DiscoverItems discoItems = discoManager.discoverItems("plays.shakespeare.lit");
// Get the discovered items of the queried XMPP entity
Iterator it = discoItems.getItems().iterator();
// Display the items of the remote XMPP entity
while (it.hasNext()) {
DiscoverItems.Item item = (DiscoverItems.Item) it.next();
System.out.println(item.getEntityID());
System.out.println(item.getNode());
System.out.println(item.getName());
}
```
Discover information about an XMPP entity
-----------------------------------------
**Description**
Once you have discovered the entity ID and name of an item, you may want to
find out more about the item. The information desired generally is of two
kinds: 1) The item's identity and 2) The features offered by the item.
This information helps you determine what actions are possible with regard to
this item (registration, search, join, etc.) as well as specific feature types
of interest, if any (e.g., for the purpose of feature negotiation).
**Usage**
Once you have your ServiceDiscoveryManager you will be able to discover
information associated with an XMPP entity. To discover the information of a
given XMPP entity send **discoverInfo(entityID)** to your
_**ServiceDiscoveryManager**_ where entityID is the ID of the entity. The
message **discoverInfo(entityID)** will answer an instance of
_**DiscoverInfo**_ that contains the discovered information.
**Examples**
In this example we can see how to discover the information of a conference
room:
```
// Obtain the ServiceDiscoveryManager associated with my XMPPConnection
ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection);
// Get the information of a given XMPP entity
// This example gets the information of a conference room
DiscoverInfo discoInfo = discoManager.discoverInfo("balconyscene@plays.shakespeare.lit");
// Get the discovered identities of the remote XMPP entity
Iterator it = discoInfo.getIdentities().iterator();
// Display the identities of the remote XMPP entity
while (it.hasNext()) {
DiscoverInfo.Identity identity = (DiscoverInfo.Identity) it.next();
System.out.println(identity.getName());
System.out.println(identity.getType());
System.out.println(identity.getCategory());
}
// Check if room is password protected
discoInfo.containsFeature("muc_passwordprotected");
```
Publish publicly available items
--------------------------------
**Description**
Publish your entity items to some kind of persistent storage. This enables
other entities to query that entity using the disco#items namespace and
receive a result even when the entity being queried is not online (or
available).
**Usage**
Once you have your ServiceDiscoveryManager you will be able to publish items
to some kind of persistent storage. To publish the items of a given XMPP
entity you have to first create an instance of _**DiscoverItems**_ and
configure it with the items to publish. Then you will have to send
**publishItems(Jid entityID, DiscoverItems discoverItems)** to your
_**ServiceDiscoveryManager**_ where entityID is the address of the XMPP entity
that will persist the items and discoverItems contains the items to publish.
**Examples**
In this example we can see how to publish new items:
```
// Obtain the ServiceDiscoveryManager associated with my XMPPConnection
ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection);
// Create a DiscoverItems with the items to publish
DiscoverItems itemsToPublish = new DiscoverItems();
Jid jid = JidCreate.from("pubsub.shakespeare.lit");
DiscoverItems.Item itemToPublish = new DiscoverItems.Item(jid);
itemToPublish.setName("Avatar");
itemToPublish.setNode("romeo/avatar");
itemToPublish.setAction(DiscoverItems.Item.UPDATE_ACTION);
itemsToPublish.addItem(itemToPublish);
// Publish the new items by sending them to the server
Jid jid2 = JidCreate.from("host");
discoManager.publishItems(jid2, itemsToPublish);
```

View File

@ -1,155 +0,0 @@
File Transfer
=============
[Back](index.md)
The file transfer extension allows the user to transmit and receive files.
* Send a file to another user
* Receiving a file from another user
* Monitoring the progress of a file transfer
**XEP related:** [XEP-95](http://www.xmpp.org/extensions/xep-0095.html) [XEP-96](http://www.xmpp.org/extensions/xep-0096.html) [XEP-65](http://www.xmpp.org/extensions/xep-0065.html) [XEP-47](http://www.xmpp.org/extensions/xep-0047.html)
Send a file to another user
---------------------------
**Description**
A user may wish to send a file to another user. The other user has the option
of accepting, rejecting, or ignoring the users request. Smack provides a
simple interface in order to enable the user to easily send a file.
**Usage**
In order to send a file you must first construct an instance of the
**_FileTransferManager_** class. In order to instantiate the manager
you should call _FileTransferManager.getInstanceFor(connection)_, where connection is an XMPPConnection instance.
Once you have your **_FileTransferManager_** you will need to create an
outgoing file transfer to send a file. The method to use on the
**_FileTransferManager_** is the **createOutgoingFileTransfer(userID)**
method. The userID you provide to this method is the fully-qualified jabber ID
of the user you wish to send the file to. A fully-qualified jabber ID consists
of a node, a domain, and a resource. The user must be connected to the
resource in order to be able to receive the file transfer.
Now that you have your **_OutgoingFileTransfer_** instance you will want to
send the file. The method to send a file is **sendFile(file, description)**.
The file you provide to this method should be a readable file on the local
file system, and the description is a short description of the file to help
the user decide whether or not they would like to recieve the file.
For information on monitoring the progress of a file transfer see the
monitoring progress section of this document.
Other means to send a file are also provided as part of the
**_OutgoingFileTransfer_**. Please consult the Javadoc for more information.
**Examples**
In this example we can see how to send a file:
```
// Create the file transfer manager
FileTransferManager manager = FileTransferManager.getInstanceFor(connection);
// Create the outgoing file transfer
OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(entityFullJid);
// Send the file
transfer.sendFile(new File("shakespeare_complete_works.txt"), "You won't believe this!");
```
Receiving a file from another user
----------------------------------
**Description**
The user may wish to receive files from another user. The process of receiving
a file is event driven, new file transfer requests are received from other
users via a listener registered with the file transfer manager.
**Usage**
In order to receive a file you must first construct an instance of the
**_FileTransferManager_** class. This class has one static factory method with one
parameter which is your XMPPConnection. In order to instantiate the manager
you should call _FileTransferManager.getInstanceFor(connection)_.
Once you have your **_FileTransferManager_** you will need to register a
listener with it. The FileTransferListener interface has one method,
**fileTransferRequest(request)**. When a request is received through this
method, you can either accept or reject the request. To help you make your
decision there are several methods in the **_FileTransferRequest_** class that
return information about the transfer request.
To accept the file transfer, call the **accept()** method. This method will create an
**_IncomingFileTransfer_**. After you have the file transfer you may start to
transfer the file by calling the **recieveFile(file)** method. The file
provided to this method will be where the data from the file transfer is saved.
Finally, to reject the file transfer the only method you need to call is
**reject()** on the **_FileTransferRequest_**.
For information on monitoring the progress of a file transfer see the
monitoring progress section of this document.
Other means to receive a file are also provided as part of the
**_IncomingFileTransfer_**. Please consult the Javadoc for more information.
**Examples**
In this example we can see how to approve or reject a file transfer request:
```
// Create the file transfer manager
final FileTransferManager manager = FileTransferManager.getInstanceFor(connection);
// Create the listener
manager.addFileTransferListener(new FileTransferListener() {
public void fileTransferRequest(FileTransferRequest request) {
// Check to see if the request should be accepted
if (shouldAccept(request)) {
// Accept it
IncomingFileTransfer transfer = request.accept();
transfer.recieveFile(new File("shakespeare_complete_works.txt"));
} else {
// Reject it
request.reject();
}
}
});
```
Monitoring the progress of a file transfer
------------------------------------------
**Description**
While a file transfer is in progress you may wish to monitor the progress of a
file transfer.
**Usage**
Both the **_IncomingFileTransfer_** and the **_OutgoingFileTransfer_** extend
the **_FileTransfer_** class which provides several methods to monitor how a
file transfer is progressing:
* **getStatus()** - The file transfer can be in several states, negotiating, rejected, cancelled, in progress, error, and complete. This method will return which state the file transfer is currently in.
* **getProgress()** - If the status of the file transfer is in progress this method will return a number between 0 and 1, 0 being the transfer has not yet started and 1 being the transfer is complete. It may also return a -1 if the transfer is not in progress.
* **isDone()** - Similar to getProgress() except it returns a _boolean_. If the state is rejected, canceled, error, or complete then true will be returned and false otherwise.
* **getError()** - If there is an error during the file transfer this method will return the type of error that occured.
**Examples**
In this example we can see how to monitor a file transfer:
```
while(!transfer.isDone()) {
if (transfer.getStatus().equals(Status.error)) {
System.out.println("ERROR!!! " + transfer.getError());
} else {
System.out.println(transfer.getStatus());
System.out.println(transfer.getProgress());
}
sleep(1000);
}
```

View File

@ -1,114 +0,0 @@
HTTP over XMPP transport
========================
[Back](index.md)
Allows the transport of HTTP communication over XMPP peer-to-peer networks.
* Discover HOXT support
* IQ exchange
Discover HOXT support
---------------------
**Description**
Before using this extension you must ensure that your counterpart supports it
also.
**Usage**
Once you have your _**ServiceDiscoveryManager**_ you will be able to discover
information associated with an XMPP entity. To discover the information of a
given XMPP entity send **discoverInfo(entityID)** to your
_**ServiceDiscoveryManager**_ where entityID is the ID of the entity. The
message **discoverInfo(entityID)** will answer with an instance of
_**DiscoverInfo**_ that contains the discovered information.
**Examples**
In this example we can see how to check if the counterpart supports HOXT:
```
// Obtain the ServiceDiscoveryManager associated with my XMPPConnection
ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection);
// Get the information of a given XMPP entity, where entityID is a Jid
DiscoverInfo discoInfo = discoManager.discoverInfo(entityID);
// Check if room is HOXT is supported
boolean isSupported = discoInfo.containsFeature("urn:xmpp:http");
```
IQ exchange
-----------
**Description**
You can use IQ's to perform HTTP requests and responses. This is applicable to
relatively short requests and responses (due to the limitation of XMPP message
size).
**Usage**
First you need to register a _**StanzaListener**_ to be able to handle
intended IQs.
For the HTTP client you:
* You create and send _**HttpOverXmppReq**_ request.
* Then you handle the _**HttpOverXmppResp**_ response in your _**StanzaListener**_.
For the HTTP server you:
* You handle the _**HttpOverXmppReq**_ requests in your _**StanzaListener**_.
* And create and send _**HttpOverXmppResp**_ responses.
**Examples**
In this example we are an HTTP client, so we send a request (POST) and handle the
response:
```
// create a request body
String urlEncodedMessage = "I_love_you";
// prepare headers
List<Header> headers = new ArrayList<>();
headers.add(new Header("Host", "juliet.capulet.com"));
headers.add(new Header("Content-Type", "application/x-www-form-urlencoded"));
headers.add(new Header("Content-Length", Integer.toString(urlEncodedMessage.length())));
// provide body or request (not mandatory, - empty body is used for GET)
AbstractHttpOverXmpp.Text child = new AbstractHttpOverXmpp.Text(urlEncodedMessage);
AbstractHttpOverXmpp.Data data = new AbstractHttpOverXmpp.Data(child);
// create request
HttpOverXmppReq req = HttpOverXmppReq.buider()
.setMethod(HttpMethod.POST)
.setResource("/mailbox")
.setHeaders(headers)
.setVersion("1.1")
.setData(data)
.build();
// add to, where jid is the Jid of the individual the packet is sent to
req.setTo(jid);
// send it
connection.sendIqWithResponseCallback(req, new StanzaListener() {
public void processStanza(Stanza iq) {
HttpOverXmppResp resp = (HttpOverXmppResp) iq;
// check HTTP response code
if (resp.getStatusCode() == 200) {
// get content of the response
NamedElement child = resp.getData().getChild();
// check which type of content of the response arrived
if (child instanceof AbstractHttpOverXmpp.Xml) {
// print the message and anxiously read if from the console ;)
System.out.println(((AbstractHttpOverXmpp.Xml) child).getText());
} else {
// process other AbstractHttpOverXmpp data child subtypes
}
}
}
});
```

View File

@ -1,147 +0,0 @@
Smack Extensions User Manual
============================
The XMPP protocol includes a base protocol and many optional extensions
typically documented as "XEP's". Smack provides the org.jivesoftware.smack
package for the core XMPP protocol, and the org.jivesoftware.smackx package
for many of the protocol extensions.
This manual provides details about each of the "smackx" extensions, including
what it is, how to use it, and some simple example code.
Currently supported XEPs of Smack (all sub-projects)
---------------------------------------------------
| Name | XEP | Version | Description |
|---------------------------------------------|--------------------------------------------------------|-----------|----------------------------------------------------------------------------------------------------------|
| Discovering Alternative XMPP Connection Methods | [XEP-0156](https://xmpp.org/extensions/xep-0156.html) | 1.3.0 | Defines ways to discover alternative connection methods. |
| Nonzas | [XEP-0360](https://xmpp.org/extensions/xep-0360.html) | n/a | Defines the term "Nonza", describing every top level stream element that is not a Stanza. |
Currently supported XEPs of smack-tcp
-------------------------------------
| Name | XEP | Version | Description |
|---------------------------------------------|--------------------------------------------------------|-----------|----------------------------------------------------------------------------------------------------------|
| [Stream Management](streammanagement.md) | [XEP-0198](https://xmpp.org/extensions/xep-0198.html) | n/a | Allows active management of an XML Stream between two XMPP entities (stanza acknowledgement, stream resumption). |
Currently supported XEPs of smack-im
------------------------------------
| Name | XEP | Version | Description |
|---------------------------------------------|--------------------------------------------------------|-----------|-----------------------------------|
| Roster Versioning | [XEP-0237](https://xmpp.org/extensions/xep-0237.html) | n/a | Efficient roster synchronization. |
Smack Extensions and currently supported XEPs of smack-extensions
-----------------------------------------------------------------
| Name | XEP | Version | Description |
|---------------------------------------------|--------------------------------------------------------|-----------|----------------------------------------------------------------------------------------------------------|
| [Data Forms](dataforms.md) | [XEP-0004](https://xmpp.org/extensions/xep-0004.html) | n/a | Allows to gather data using Forms. |
| Last Activity | [XEP-0012](https://xmpp.org/extensions/xep-0012.html) | n/a | Communicating information about the last activity associated with an XMPP entity. |
| Flexible Offline Message Retrieval | [XEP-0013](https://xmpp.org/extensions/xep-0013.html) | n/a | Extension for flexible, POP3-like handling of offline messages. |
| [Privacy Lists](privacy.md) | [XEP-0016](https://xmpp.org/extensions/xep-0016.html) | n/a | Enabling or disabling communication with other entities. |
| [Service Discovery](disco.md) | [XEP-0030](https://xmpp.org/extensions/xep-0030.html) | n/a | Allows to discover services in XMPP entities. |
| Extended Stanza Addressing | [XEP-0033](https://xmpp.org/extensions/xep-0033.html) | n/a | Allows to include headers in stanzas in order to specifiy multiple recipients or sub-addresses. |
| [Multi User Chat](muc.md) | [XEP-0045](https://xmpp.org/extensions/xep-0045.html) | n/a | Allows configuration of, participation in, and administration of individual text-based conference rooms. |
| In-Band Bytestreams | [XEP-0047](https://xmpp.org/extensions/xep-0047.html) | n/a | Enables any two entities to establish a one-to-one bytestream between themselves using plain XMPP. |
| Bookmarks | [XEP-0048](https://xmpp.org/extensions/xep-0048.html) | n/a | Bookmarks, for e.g. MUC and web pages. |
| [Private Data](privatedata.md) | [XEP-0049](https://xmpp.org/extensions/xep-0049.html) | n/a | Manages private data. |
| Ad-Hoc Commands | [XEP-0050](https://xmpp.org/extensions/xep-0050.html) | n/a | Advertising and executing application-specific commands. |
| vcard-temp | [XEP-0054](https://xmpp.org/extensions/xep-0054.html) | n/a | The vCard-XML format currently in use. |
| Jabber Search | [XEP-0055](https://xmpp.org/extensions/xep-0055.html) | n/a | Search information repositories on the XMPP network. |
| Result Set Management | [XEP-0059](https://xmpp.org/extensions/xep-0059.html) | n/a | Page through and otherwise manage the receipt of large result sets |
| [PubSub](pubsub.md) | [XEP-0060](https://xmpp.org/extensions/xep-0060.html) | n/a | Generic publish and subscribe functionality. |
| SOCKS5 Bytestreams | [XEP-0065](https://xmpp.org/extensions/xep-0065.html) | n/a | Out-of-band bytestream between any two XMPP entities. |
| Field Standardization for Data Forms | [XEP-0068](https://xmpp.org/extensions/xep-0068.html) | n/a | Standardized field variables used in the context of jabber:x:data forms. |
| [XHTML-IM](xhtml.md) | [XEP-0071](https://xmpp.org/extensions/xep-0071.html) | n/a | Allows send and receiving formatted messages using XHTML. |
| In-Band Registration | [XEP-0077](https://xmpp.org/extensions/xep-0077.html) | n/a | In-band registration with XMPP services. |
| Advanced Message Processing | [XEP-0079](https://xmpp.org/extensions/xep-0079.html) | n/a | Enables entities to request, and servers to perform, advanced processing of XMPP message stanzas. |
| User Location | [XEP-0080](https://xmpp.org/extensions/xep-0080.html) | n/a | Enabled communicating information about the current geographical or physical location of an entity. |
| XMPP Date Time Profiles | [XEP-0082](https://xmpp.org/extensions/xep-0082.html) | n/a | Standardization of Date and Time representation in XMPP. |
| Chat State Notifications | [XEP-0085](https://xmpp.org/extensions/xep-0085.html) | n/a | Communicating the status of a user in a chat session. |
| [Time Exchange](time.md) | [XEP-0090](https://xmpp.org/extensions/xep-0090.html) | n/a | Allows local time information to be shared between users. |
| Software Version | [XEP-0092](https://xmpp.org/extensions/xep-0092.html) | n/a | Retrieve and announce the software application of an XMPP entity. |
| Stream Initiation | [XEP-0095](https://xmpp.org/extensions/xep-0095.html) | n/a | Initiating a data stream between any two XMPP entities. |
| [SI File Transfer](filetransfer.md) | [XEP-0096](https://xmpp.org/extensions/xep-0096.html) | n/a | Transfer files between two users over XMPP. |
| User Mood | [XEP-0107](https://xmpp.org/extensions/xep-0107.html) | 1.2.1 | Communicate the users current mood. |
| [Entity Capabilities](caps.md) | [XEP-0115](https://xmpp.org/extensions/xep-0115.html) | n/a | Broadcasting and dynamic discovery of entity capabilities. |
| User Tune | [XEP-0118](https://xmpp.org/extensions/xep-0118.html) | n/a | Defines a payload format for communicating information about music to which a user is listening. |
| Data Forms Validation | [XEP-0122](https://xmpp.org/extensions/xep-0122.html) | n/a | Enables an application to specify additional validation guidelines . |
| Stanza Headers and Internet Metadata (SHIM) | [XEP-0131](https://xmpp.org/extensions/xep-0131.html) | 1.2 | Add Metadata Headers to Stanzas. |
| Service Administration | [XEP-0133](https://xmpp.org/extensions/xep-0133.html) | n/a | Recommended best practices for service-level administration of servers and components using Ad-Hoc Commands. |
| Stream Compression | [XEP-0138](https://xmpp.org/extensions/xep-0138.html) | n/a | Support for optional compression of the XMPP stream.
| Data Forms Layout | [XEP-0141](https://xmpp.org/extensions/xep-0141.html) | n/a | Enables an application to specify form layouts. |
| Personal Eventing Protocol | [XEP-0163](https://xmpp.org/extensions/xep-0163.html) | n/a | Using the XMPP publish-subscribe protocol to broadcast state change events associated with an XMPP account. |
| [Jingle](jingle.html) | [XEP-0166](https://xmpp.org/extensions/xep-0166.html) | n/a | Initiate and manage sessions between two XMPP entities. |
| User Nickname | [XEP-0172](https://xmpp.org/extensions/xep-0172.html) | n/a | Communicate user nicknames. |
| Message Delivery Receipts | [XEP-0184](https://xmpp.org/extensions/xep-0184.html) | n/a | Extension for message delivery receipts. The sender can request notification that the message has been delivered. |
| [Blocking Command](blockingcommand.md) | [XEP-0191](https://xmpp.org/extensions/xep-0191.html) | n/a | Communications blocking that is intended to be simpler than privacy lists (XEP-0016). |
| XMPP Ping | [XEP-0199](https://xmpp.org/extensions/xep-0199.html) | n/a | Sending application-level pings over XML streams.
| Entity Time | [XEP-0202](https://xmpp.org/extensions/xep-0202.html) | n/a | Allows entities to communicate their local time |
| Delayed Delivery | [XEP-0203](https://xmpp.org/extensions/xep-0203.html) | n/a | Extension for communicating the fact that an XML stanza has been delivered with a delay. |
| XMPP Over BOSH | [XEP-0206](https://xmpp.org/extensions/xep-0206.html) | n/a | Use Bidirectional-streams Over Synchronous HTTP (BOSH) to transport XMPP stanzas. |
| Data Forms Media Element | [XEP-0221](https://xmpp.org/extensions/xep-0221.html) | n/a | Allows to include media data in XEP-0004 data forms. |
| Attention | [XEP-0224](https://xmpp.org/extensions/xep-0224.html) | n/a | Getting attention of another user. |
| Bits of Binary | [XEP-0231](https://xmpp.org/extensions/xep-0231.html) | n/a | Including or referring to small bits of binary data in an XML stanza. |
| Software Information | [XEP-0232](https://xmpp.org/extensions/xep-0232.html) | 0.3 | Allows an entity to provide detailed data about itself in Service Discovery responses. |
| Best Practices for Resource Locking | [XEP-0296](https://xmpp.org/extensions/xep-0296.html) | n/a | Specifies best practices to be followed by Jabber/XMPP clients about when to lock into, and unlock away from, resources. |
| Stanza Forwarding | [XEP-0297](https://xmpp.org/extensions/xep-0297.html) | n/a | Allows forwarding of Stanzas. |