mirror of
https://github.com/vanitasvitae/Smack.git
synced 2025-09-09 17:19:39 +02:00
Convert html documentation to markdown
This commit is contained in:
parent
450015bf40
commit
344148eaed
56 changed files with 3545 additions and 4217 deletions
|
@ -1,63 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Entity Capabilities</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="header">Entity Capabilities</div><p>
|
||||
This section details the usage of Smacks implementation of Entity Capabilities.
|
||||
</p>
|
||||
<b>XEP related:</b> <a href="http://xmpp.org/extensions/xep-0115.html">XEP-0115: Entity Capabilities</a>
|
||||
|
||||
<hr>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
Entity Capabilities is a 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 (<a href="http://xmpp.org/extensions/xep-0030.html">XEP-0030</a>).
|
||||
|
||||
</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
Entity Capabilities work silenty in 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 <i><b>EntityCapsManager</b></i>.<br>
|
||||
|
||||
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.
|
||||
</p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
Enable Entity Capabilities
|
||||
<br>
|
||||
<blockquote>
|
||||
<pre>
|
||||
<font color="#3f7f5f">// Get an instance of entity caps manager for the specified connection</font>
|
||||
EntityCapsManager mgr = EntityCapsManager.getInstanceFor(connection);
|
||||
|
||||
<font color="#3f7f5f">// Enable entity capabilities</font>
|
||||
mgr.enableEntityCaps();
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
Configure a persistent cache for Entity Capabilities
|
||||
<br>
|
||||
<blockquote>
|
||||
<pre>
|
||||
<font color="#3f7f5f">// Get an instance of entity caps manager for the specified connection</font>
|
||||
EntityCapsManager mgr = EntityCapsManager.getInstanceFor(connection);
|
||||
|
||||
<font color="#3f7f5f">// Create an cache, see smackx.entitycaps.cache for pre-defined cache implementations</font>
|
||||
EntityCapsPersistentCache cache = new SimpleDirectoryPersistentCache(new File("/foo/cachedir"));
|
||||
|
||||
<font color="#3f7f5f">// Set the cache</font>
|
||||
mgr.setPersistentCache(cache);
|
||||
</pre>
|
||||
</blockquote>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
47
documentation/extensions/caps.md
Normal file
47
documentation/extensions/caps.md
Normal file
|
@ -0,0 +1,47 @@
|
|||
Entity Capabilities
|
||||
===================
|
||||
|
||||
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 a 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 silenty in 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);
|
||||
```
|
|
@ -1,137 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Data Forms</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="header">Data Forms</div><p>
|
||||
|
||||
Allows to exchange structured data between users and applications for common
|
||||
tasks such as registration and searching using Forms.
|
||||
|
||||
<ul>
|
||||
<li><a href="#gather">Create a Form to fill out</a></li>
|
||||
<li><a href="#fillout">Answer a Form</a></li>
|
||||
</ul>
|
||||
<b>XEP related:</b> <a href="http://www.xmpp.org/extensions/xep-0004.html">XEP-4</a>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="gather">Create a Form to fill out</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
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 the Form and finally
|
||||
send the Form to the data-providing entity.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
In order to create a Form to fill out use the <i><b>Form</b></i>'s constructor passing the constant
|
||||
<b>Form.TYPE_FORM</b> 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 <i><b>FormField</b></i> use the <i><b>FormField</b></i>'s
|
||||
constructor specifying the variable name of the field as the parameter. Then use <b>setType(String type)</b>
|
||||
to set the field's type (e.g. FormField.TYPE_HIDDEN, FormField.TYPE_TEXT_SINGLE). Once we have the
|
||||
<i><b>Form</b></i> instance and the <i><b>FormFields</b></i> the last step is to send <b>addField(FormField field)</b>
|
||||
for each field that we want to add to the form.</p><p>
|
||||
|
||||
Once the form to fill out is finished we will want to send it in a message. Send <b>getDataFormToSend()</b> to
|
||||
the form and add the answer as an extension to the message to send.</p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to create and send a form to fill out: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Create a new form to gather data</font>
|
||||
Form formToSend = new Form(Form.TYPE_FORM);
|
||||
formToSend.setInstructions(
|
||||
"Fill out this form to report your case.\nThe case will be created automatically.");
|
||||
formToSend.setTitle("Case configurations");
|
||||
<font color="#3f7f5f">// Add a hidden variable to the form</font>
|
||||
FormField field = new FormField("hidden_var");
|
||||
field.setType(FormField.TYPE_HIDDEN);
|
||||
field.addValue("Some value for the hidden variable");
|
||||
formToSend.addField(field);
|
||||
<font color="#3f7f5f">// Add a fixed variable to the form</font>
|
||||
field = new FormField();
|
||||
field.addValue("Section 1: Case description");
|
||||
formToSend.addField(field);
|
||||
<font color="#3f7f5f">// Add a text-single variable to the form</font>
|
||||
field = new FormField("name");
|
||||
field.setLabel("Enter a name for the case");
|
||||
field.setType(FormField.TYPE_TEXT_SINGLE);
|
||||
formToSend.addField(field);
|
||||
<font color="#3f7f5f">// Add a text-multi variable to the form</font>
|
||||
field = new FormField("description");
|
||||
field.setLabel("Enter a description");
|
||||
field.setType(FormField.TYPE_TEXT_MULTI);
|
||||
formToSend.addField(field);
|
||||
|
||||
<font color="#3f7f5f">// Create a chat with "user2@host.com"</font>
|
||||
Chat chat = conn1.createChat("user2@host.com" );
|
||||
|
||||
Message msg = chat.createMessage();
|
||||
msg.setBody("To enter a case please fill out this form and send it back to me");
|
||||
<font color="#3f7f5f">// Add the form to fill out to the message to send</font>
|
||||
msg.addExtension(formToSend.getDataFormToSend());
|
||||
|
||||
<font color="#3f7f5f">// Send the message with the form to fill out</font>
|
||||
chat.sendMessage(msg);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="fillout">Answer a Form</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
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.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
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.</p><p>
|
||||
|
||||
In order to create a new <i><b>Form</b></i> to complete based on the original <i><b>Form</b></i> just send
|
||||
<b>createAnswerForm()</b> to the original <i><b>Form</b></i>. Once you have a valid form that could be actually
|
||||
completed all you have to do is send <b>setAnswer(String variable, String value)</b> to the form where variable
|
||||
is the variable of the <i><b>FormField</b></i> that you want to answer and value is the String representation
|
||||
of the answer. If the answer consist of several values you could then use <b>setAnswer(String variable, List values)</b>
|
||||
where values is a List of Strings.</p><p>
|
||||
|
||||
Once the form has been completed we will want to send it back in a message. Send <b>getDataFormToSend()</b> to
|
||||
the form and add the answer as an extension to the message to send back.</p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to retrieve a form to fill out, complete the form and send it back: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Get the message with the form to fill out</font>
|
||||
Message msg2 = chat2.nextMessage();
|
||||
<font color="#3f7f5f">// Retrieve the form to fill out from the message</font>
|
||||
Form formToRespond = Form.getFormFrom(msg2);
|
||||
<font color="#3f7f5f">// Obtain the form to send with the replies</font>
|
||||
Form completedForm = formToRespond.createAnswerForm();
|
||||
<font color="#3f7f5f">// Add the answers to the form</font>
|
||||
completedForm.setAnswer("name", "Credit card number invalid");
|
||||
completedForm.setAnswer(
|
||||
"description",
|
||||
"The ATM says that my credit card number is invalid. What's going on?");
|
||||
|
||||
msg2 = chat2.createMessage();
|
||||
msg2.setBody("To enter a case please fill out this form and send it back to me");
|
||||
<font color="#3f7f5f">// Add the completed form to the message to send back</font>
|
||||
msg2.addExtension(completedForm.getDataFormToSend());
|
||||
<font color="#3f7f5f">// Send the message with the completed form</font>
|
||||
chat2.sendMessage(msg2);
|
||||
</pre>
|
||||
</blockquote>
|
||||
</body>
|
||||
|
||||
</html>
|
127
documentation/extensions/dataforms.md
Normal file
127
documentation/extensions/dataforms.md
Normal file
|
@ -0,0 +1,127 @@
|
|||
Data Forms
|
||||
==========
|
||||
|
||||
Allows to exchange 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 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 **Form.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(String 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(Form.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 = conn1.createChat("user2@host.com" );
|
||||
Message msg = chat.createMessage();
|
||||
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.sendMessage(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 could be actually 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 consist 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
|
||||
Message msg2 = chat2.nextMessage();
|
||||
// Retrieve the form to fill out from the message
|
||||
Form formToRespond = Form.getFormFrom(msg2);
|
||||
// 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");
|
||||
msg2 = chat2.createMessage();
|
||||
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
|
||||
chat2.sendMessage(msg2);
|
||||
```
|
|
@ -1,236 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Service Discovery</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="header">Service Discovery</div><p>
|
||||
|
||||
The service discovery extension allows to discover items and information about XMPP
|
||||
entities. Follow these links to learn how to use this extension.
|
||||
|
||||
<ul>
|
||||
<li><a href="#discoregister">Manage XMPP entity features</a></li>
|
||||
<li><a href="#disconodeinfo">Provide node information</a></li>
|
||||
<li><a href="#discoitems">Discover items associated with an XMPP entity</a></li>
|
||||
<li><a href="#discoinfo">Discover information about an XMPP entity</a></li>
|
||||
<li><a href="#discopublish">Publish publicly available items</a></li>
|
||||
</ul>
|
||||
<b>XEP related:</b> <a href="http://www.xmpp.org/extensions/xep-0030.html">XEP-30</a>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="discoregister">Manage XMPP entity features</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
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.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
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 <b>getInstanceFor(connection)</b> to the class <i><b>ServiceDiscoveryManager</b></i> where
|
||||
connection is your XMPPConnection.<br></p>
|
||||
|
||||
<p>Once you have your ServiceDiscoveryManager you will be able to manage the supported features. To
|
||||
register a new feature send <b>addFeature(feature)</b> to your <i><b>ServiceDiscoveryManager</b></i>
|
||||
where feature is a String that represents the supported feature. To remove a supported feature send
|
||||
<b>removeFeature(feature)</b> to your <i><b>ServiceDiscoveryManager</b></i> where feature is a
|
||||
String that represents the feature to remove.</p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to add and remove supported features: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Obtain the ServiceDiscoveryManager associated with my XMPPConnection</font>
|
||||
ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection);
|
||||
|
||||
<font color="#3f7f5f">// Register that a new feature is supported by this XMPP entity</font>
|
||||
discoManager.addFeature(namespace1);
|
||||
|
||||
<font color="#3f7f5f">// Remove the specified feature from the supported features by this XMPP entity</font>
|
||||
discoManager.removeFeature(namespace2);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="disconodeinfo">Provide node information</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
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.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
In order to configure the associated nodes within the Smack client you will need to create a
|
||||
NodeInformationProvider and register it with the <i><b>ServiceDiscoveryManager</b></i>. To get
|
||||
your ServiceDiscoveryManager send <b>getInstanceFor(connection)</b> to the class <i><b>ServiceDiscoveryManager</b></i>
|
||||
where connection is your XMPPConnection.<br></p>
|
||||
|
||||
<p>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 <b>setNodeInformationProvider(String node, NodeInformationProvider listener)</b>
|
||||
to your <i><b>ServiceDiscoveryManager</b></i> where node is the item non-addressable as a JID and
|
||||
listener is the <i><b>NodeInformationProvider</b></i> to register. To unregister a <i><b>NodeInformationProvider</b></i>
|
||||
send <b>removeNodeInformationProvider(String node)</b> to your <i><b>ServiceDiscoveryManager</b></i> where
|
||||
node is the item non-addressable as a JID whose information provider we want to unregister.</p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
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": <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Set the NodeInformationProvider that will provide information about the</font>
|
||||
<font color="#3f7f5f">// joined rooms whenever a disco request is received </font>
|
||||
ServiceDiscoveryManager.getInstanceFor(connection).setNodeInformationProvider(
|
||||
<font color="#0000FF">"http://jabber.org/protocol/muc#rooms"</font>,
|
||||
new NodeInformationProvider() {
|
||||
public List getNodeItems() {
|
||||
ArrayList answer = new ArrayList();
|
||||
Iterator rooms = MultiUserChat.getJoinedRooms(connection);
|
||||
while (rooms.hasNext()) {
|
||||
answer.add(new DiscoverItems.Item((String)rooms.next()));
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
});
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="discoitems">Discover items associated with an XMPP entity</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
In order to obtain information about a specific item you have to first discover the items available
|
||||
in an XMPP entity.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
<p>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 <b>discoverItems(entityID)</b>
|
||||
to your <i><b>ServiceDiscoveryManager</b></i> where entityID is the ID of the entity. The message
|
||||
<b>discoverItems(entityID)</b> will answer an instance of <i><b>DiscoverItems</b></i> that contains
|
||||
the discovered items.</p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to discover the items associated with an online catalog service: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Obtain the ServiceDiscoveryManager associated with my XMPPConnection</font>
|
||||
ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection);
|
||||
|
||||
<font color="#3f7f5f">// Get the items of a given XMPP entity</font>
|
||||
<font color="#3f7f5f">// This example gets the items associated with online catalog service</font>
|
||||
DiscoverItems discoItems = discoManager.discoverItems("plays.shakespeare.lit");
|
||||
|
||||
<font color="#3f7f5f">// Get the discovered items of the queried XMPP entity</font>
|
||||
Iterator it = discoItems.getItems();
|
||||
<font color="#3f7f5f">// Display the items of the remote XMPP entity</font>
|
||||
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());
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="discoinfo">Discover information about an XMPP entity</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
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.</p>
|
||||
|
||||
<p>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).</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
<p>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 <b>discoverInfo(entityID)</b>
|
||||
to your <i><b>ServiceDiscoveryManager</b></i> where entityID is the ID of the entity. The message
|
||||
<b>discoverInfo(entityID)</b> will answer an instance of <i><b>DiscoverInfo</b></i> that contains
|
||||
the discovered information.</p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to discover the information of a conference room: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Obtain the ServiceDiscoveryManager associated with my XMPPConnection</font>
|
||||
ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection);
|
||||
|
||||
<font color="#3f7f5f">// Get the information of a given XMPP entity</font>
|
||||
<font color="#3f7f5f">// This example gets the information of a conference room</font>
|
||||
DiscoverInfo discoInfo = discoManager.discoverInfo("balconyscene@plays.shakespeare.lit");
|
||||
|
||||
<font color="#3f7f5f">// Get the discovered identities of the remote XMPP entity</font>
|
||||
Iterator it = discoInfo.getIdentities();
|
||||
<font color="#3f7f5f">// Display the identities of the remote XMPP entity</font>
|
||||
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());
|
||||
}
|
||||
|
||||
<font color="#3f7f5f">// Check if room is password protected</font>
|
||||
discoInfo.containsFeature("muc_passwordprotected");
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="discopublish">Publish publicly available items</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
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).</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
<p>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 <i><b>DiscoverItems</b></i> and configure it with the items to publish. Then you will have to
|
||||
send <b>publishItems(String entityID, DiscoverItems discoverItems)</b> to your <i><b>ServiceDiscoveryManager</b></i>
|
||||
where entityID is the address of the XMPP entity that will persist the items and discoverItems contains the items
|
||||
to publish.</p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to publish new items: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Obtain the ServiceDiscoveryManager associated with my XMPPConnection</font>
|
||||
ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection);
|
||||
|
||||
<font color="#3f7f5f">// Create a DiscoverItems with the items to publish</font>
|
||||
DiscoverItems itemsToPublish = new DiscoverItems();
|
||||
DiscoverItems.Item itemToPublish = new DiscoverItems.Item("pubsub.shakespeare.lit");
|
||||
itemToPublish.setName("Avatar");
|
||||
itemToPublish.setNode("romeo/avatar");
|
||||
itemToPublish.setAction(DiscoverItems.Item.UPDATE_ACTION);
|
||||
itemsToPublish.addItem(itemToPublish);
|
||||
|
||||
<font color="#3f7f5f">// Publish the new items by sending them to the server</font>
|
||||
discoManager.publishItems("host", itemsToPublish);
|
||||
</pre>
|
||||
</blockquote>
|
||||
</body>
|
||||
|
||||
</html>
|
224
documentation/extensions/disco.md
Normal file
224
documentation/extensions/disco.md
Normal file
|
@ -0,0 +1,224 @@
|
|||
Service Discovery
|
||||
=================
|
||||
|
||||
The service discovery extension allows 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 getNodeItems() {
|
||||
ArrayList answer = new ArrayList();
|
||||
Iterator rooms = MultiUserChat.getJoinedRooms(connection);
|
||||
while (rooms.hasNext()) {
|
||||
answer.add(new DiscoverItems.Item((String)rooms.next()));
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
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();
|
||||
// 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();
|
||||
// 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(String 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();
|
||||
DiscoverItems.Item itemToPublish = new DiscoverItems.Item("pubsub.shakespeare.lit");
|
||||
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
|
||||
discoManager.publishItems("host", itemsToPublish);
|
||||
```
|
|
@ -1,178 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>File Transfer</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="header">File Transfer</div><p>
|
||||
|
||||
The file transfer extension allows the user to transmit and receive files.
|
||||
|
||||
<ul>
|
||||
<li><a href="#sendfile">Send a file to another user</a></li>
|
||||
<li><a href="#recievefile">Recieving a file from another user</a></li>
|
||||
<li><a href="#monitorprogress">Monitoring the progress of a file transfer</a></li>
|
||||
</ul>
|
||||
<b>XEP related:</b> <a href="http://www.xmpp.org/extensions/xep-0095.html">XEP-95</a>
|
||||
<a href="http://www.xmpp.org/extensions/xep-0096.html">XEP-96</a>
|
||||
<a href="http://www.xmpp.org/extensions/xep-0065.html">XEP-65</a>
|
||||
<a href="http://www.xmpp.org/extensions/xep-0047.html">XEP-47</a>
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="sendfile">Send a file to another user</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
A user may wish to send a file to another user. The other user has the option of acception,
|
||||
rejecting, or ignoring the users request. Smack provides a simple interface in order
|
||||
to enable the user to easily send a file.
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
In order to send a file you must first construct an instance of the <b><i>FileTransferManager</i></b>
|
||||
class. This class has one constructor with one parameter which is your XMPPConnection.
|
||||
In order to instantiate the manager you should call <i>new FileTransferManager(connection)</i>
|
||||
|
||||
<p>Once you have your <b><i>FileTransferManager</i></b> you will need to create an outgoing
|
||||
file transfer to send a file. The method to use on the <b><i>FileTransferManager</i></b>
|
||||
is the <b>createOutgoingFileTransfer(userID)</b> 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 recieve the file transfer.
|
||||
|
||||
<p>Now that you have your <b><i>OutgoingFileTransfer</i></b> instance you will want
|
||||
to send the file. The method to send a file is <b>sendFile(file, description)</b>. 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.
|
||||
|
||||
<p>For information on monitoring the progress of a file transfer see the <a href="#monitorprogress">monitoring progress</a>
|
||||
section of this document.
|
||||
|
||||
<p>Other means to send a file are also provided as part of the <b><i>OutgoingFileTransfer</i></b>. Please
|
||||
consult the Javadoc for more information.
|
||||
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to send a file: <br>
|
||||
<blockquote>
|
||||
<pre>
|
||||
<font color="#3f7f5f">// Create the file transfer manager</font>
|
||||
FileTransferManager manager = new FileTransferManager(connection);
|
||||
|
||||
<font color="#3f7f5f">// Create the outgoing file transfer</font>
|
||||
OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(<font color="#0000FF">"romeo@montague.net"</font>);
|
||||
|
||||
<font color="#3f7f5f">// Send the file</font>
|
||||
transfer.sendFile(new File(<font color="#0000FF">"shakespeare_complete_works.txt"</font>), <font color="#0000FF">"You won't believe this!"</font>);
|
||||
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="recievefile">Recieving a file from another user</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
The user may wish to recieve files from another user. The process of recieving a file is event driven,
|
||||
new file transfer requests are recieved from other users via a listener registered with the file transfer
|
||||
manager.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
In order to recieve a file you must first construct an instance of the <b><i>FileTransferManager</i></b>
|
||||
class. This class has one constructor with one parameter which is your XMPPConnection.
|
||||
In order to instantiate the manager you should call <i>new FileTransferManager(connection)</i>
|
||||
|
||||
<p>Once you have your <b><i>FileTransferManager</i></b> you will need to register a listener
|
||||
with it. The FileTransferListner interface has one method, <b>fileTransferRequest(request)</b>.
|
||||
When a request is recieved through this method, you can either accept or reject the
|
||||
request. To help you make your decision there are several methods in the <b><i>FileTransferRequest</i></b>
|
||||
class that return information about the transfer request.
|
||||
|
||||
<p>To accept the file transfer, call the <b>accept()</b>,
|
||||
this method will create an <b><i>IncomingFileTransfer</i></b>. After you have the file transfer you may start
|
||||
to transfer the file by calling the <b>recieveFile(file)</b> method.
|
||||
The file provided to this method will be where the data from thefile transfer is saved.</p>
|
||||
|
||||
<p>Finally, to reject the file transfer the only method you need to call is <b>reject()</b>
|
||||
on the <b><i>IncomingFileTransfer</i></b>.
|
||||
|
||||
<p>For information on monitoring the progress of a file transfer see the <a href="#monitorprogress">monitoring progress</a>
|
||||
section of this document.
|
||||
|
||||
<p>Other means to recieve a file are also provided as part of the <b><i>IncomingFileTransfer</i></b>. Please
|
||||
consult the Javadoc for more information.
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to approve or reject a file transfer request: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Create the file transfer manager</font>
|
||||
final FileTransferManager manager = new FileTransferManager(connection);
|
||||
|
||||
<font color="#3f7f5f">// Create the listener</font>
|
||||
manager.addFileTransferListener(new FileTransferListener() {
|
||||
public void fileTransferRequest(FileTransferRequest request) {
|
||||
<font color="#3f7f5f">// Check to see if the request should be accepted</font>
|
||||
if(shouldAccept(request)) {
|
||||
<font color="#3f7f5f">// Accept it</font>
|
||||
IncomingFileTransfer transfer = request.accept();
|
||||
transfer.recieveFile(new File(<font color="#0000FF">"shakespeare_complete_works.txt"</font>));
|
||||
} else {
|
||||
<font color="#3f7f5f">// Reject it</font>
|
||||
request.reject();
|
||||
}
|
||||
}
|
||||
});
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="monitorprogress">Monitoring the progress of a file transfer</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
While a file transfer is in progress you may wish to monitor the progress of a file transfer.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
<p>Both the <b><i>IncomingFileTransfer</i></b> and the <b><i>OutgoingFileTransfer</i></b>
|
||||
extend the <b><i>FileTransfer</i></b> class which provides several methods to monitor
|
||||
how a file transfer is progressing:
|
||||
<ul>
|
||||
<li><b>getStatus()</b> - The file transfer can be in several states, negotiating, rejected, canceled,
|
||||
in progress, error, and complete. This method will return which state the file transfer is currently in.
|
||||
<li><b>getProgress()</b> - 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.
|
||||
<li><b>isDone()</b> - Similar to getProgress() except it returns a <i>boolean</i>. If the state is
|
||||
rejected, canceled, error, or complete then true will be returned and false otherwise.
|
||||
<li><b>getError()</b> - If there is an error during the file transfer this method will
|
||||
return the type of error that occured.
|
||||
</ul>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to monitor a file transfer: <br>
|
||||
<blockquote>
|
||||
<pre> while(!transfer.isDone()) {
|
||||
if(transfer.getStatus().equals(Status.ERROR)) {
|
||||
System.out.println(<font color="#0000FF">"ERROR!!! "</font> + transfer.getError());
|
||||
} else {
|
||||
System.out.println(transfer.getStatus());
|
||||
System.out.println(transfer.getProgress());
|
||||
}
|
||||
sleep(1000);
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
</body>
|
||||
|
||||
</html>
|
148
documentation/extensions/filetransfer.md
Normal file
148
documentation/extensions/filetransfer.md
Normal file
|
@ -0,0 +1,148 @@
|
|||
File Transfer
|
||||
=============
|
||||
|
||||
The file transfer extension allows the user to transmit and receive files.
|
||||
|
||||
* Send a file to another user
|
||||
* Recieving 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 acception, 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. This class has one constructor with one
|
||||
parameter which is your XMPPConnection. In order to instantiate the manager
|
||||
you should call _new FileTransferManager(connection)_
|
||||
|
||||
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 recieve 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 = new FileTransferManager(connection);
|
||||
// Create the outgoing file transfer
|
||||
OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer("romeo@montague.net");
|
||||
// Send the file
|
||||
transfer.sendFile(new File("shakespeare_complete_works.txt"), "You won't believe this!");
|
||||
```
|
||||
|
||||
Recieving a file from another user
|
||||
----------------------------------
|
||||
|
||||
**Description**
|
||||
|
||||
The user may wish to recieve files from another user. The process of recieving
|
||||
a file is event driven, new file transfer requests are recieved from other
|
||||
users via a listener registered with the file transfer manager.
|
||||
|
||||
**Usage**
|
||||
|
||||
In order to recieve a file you must first construct an instance of the
|
||||
**_FileTransferManager_** class. This class has one constructor with one
|
||||
parameter which is your XMPPConnection. In order to instantiate the manager
|
||||
you should call _new FileTransferManager(connection)_
|
||||
|
||||
Once you have your **_FileTransferManager_** you will need to register a
|
||||
listener with it. The FileTransferListner interface has one method,
|
||||
**fileTransferRequest(request)**. When a request is recieved 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()**, 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 thefile transfer is saved.
|
||||
|
||||
Finally, to reject the file transfer the only method you need to call is
|
||||
**reject()** on the **_IncomingFileTransfer_**.
|
||||
|
||||
For information on monitoring the progress of a file transfer see the
|
||||
monitoring progress section of this document.
|
||||
|
||||
Other means to recieve 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 = new FileTransferManager(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, canceled, 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);
|
||||
}
|
||||
```
|
|
@ -1,156 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>HTTP over XMPP transport</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="header">HTTP over XMPP transport</div><p>
|
||||
|
||||
Allows to transport HTTP communication over XMPP peer-to-peer networks.<p>
|
||||
|
||||
<ul>
|
||||
<li><a href="#disco">Discover HOXT support</a></li>
|
||||
<li><a href="#iqexchange">IQ exchange</a></li>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="disco">Discover HOXT support</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
Before using this extension you must ensure that your counterpart supports it also.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
<p>Once you have your <i><b>ServiceDiscoveryManager</b></i> you will be able to discover information associated with
|
||||
an XMPP entity. To discover the information of a given XMPP entity send <b>discoverInfo(entityID)</b>
|
||||
to your <i><b>ServiceDiscoveryManager</b></i> where entityID is the ID of the entity. The message
|
||||
<b>discoverInfo(entityID)</b> will answer an instance of <i><b>DiscoverInfo</b></i> that contains
|
||||
the discovered information.</p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to check if the counterpart supports HOXT: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Obtain the ServiceDiscoveryManager associated with my XMPPConnection</font>
|
||||
ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection);
|
||||
|
||||
<font color="#3f7f5f">// Get the information of a given XMPP entity</font>
|
||||
DiscoverInfo discoInfo = discoManager.discoverInfo("juliet@capulet.com");
|
||||
|
||||
<font color="#3f7f5f">// Check if room is HOXT is supported</font>
|
||||
discoInfo.containsFeature("urn:xmpp:http");
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="iqexchange">IQ exchange</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
You can use IQ's to perform HTTP requests and responses.
|
||||
This is applicable to relatively short requests and responses (due to limitation of XMPP message size).</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
<p>First you need to register a <i><b>PacketListener</b></i> to be able to handle intended IQs.<p>
|
||||
For the HTTP client you:
|
||||
<ul>
|
||||
<li>You create and send <i><b>HttpOverXmppReq</b></i> request.</li>
|
||||
<li>Then you handle the <i><b>HttpOverXmppResp</b></i> response in your <i><b>PacketListener</b></i>.</li>
|
||||
</ul>
|
||||
|
||||
For the HTTP server you:
|
||||
<ul>
|
||||
<li>You handle the <i><b>HttpOverXmppReq</b></i> requests in your <i><b>PacketListener</b></i>.</li>
|
||||
<li>And create and send <i><b>HttpOverXmppResp</b></i> responses.</li>
|
||||
</ul>
|
||||
|
||||
</p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we are HTTP client, so we send request (POST) and handle the response: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// register listener for IQ packets</font>
|
||||
connection.addPacketListener(new IqPacketListener(), new PacketTypeFilter(IQ.class));
|
||||
|
||||
<font color="#3f7f5f">// create a request body</font>
|
||||
String urlEncodedMessage = "I_love_you";
|
||||
|
||||
<font color="#3f7f5f">// create request</font>
|
||||
HttpOverXmppReq.Req req = new HttpOverXmppReq.Req(HttpMethod.POST, "/mailbox");
|
||||
req.setVersion("1.1");
|
||||
|
||||
<font color="#3f7f5f">// prepare headers</font>
|
||||
Set<Header> set = new HashSet<Header>();
|
||||
set.add(new Header("Host", "juliet.capulet.com"));
|
||||
set.add(new Header("Content-Type", "application/x-www-form-urlencoded"));
|
||||
set.add(new Header("Content-Length", Integer.toString(urlEncodedMessage.length())));
|
||||
req.setHeaders(new HeadersExtension(set));
|
||||
|
||||
<font color="#3f7f5f">// provide body or request (not mandatory, - empty body is used for GET)</font>
|
||||
AbstractHttpOverXmpp.Text child = new AbstractHttpOverXmpp.Text(urlEncodedMessage);
|
||||
AbstractHttpOverXmpp.Data data = new AbstractHttpOverXmpp.Data(child);
|
||||
req.setData(data);
|
||||
|
||||
<font color="#3f7f5f">// create IQ packet</font>
|
||||
HttpOverXmppReq packet = new HttpOverXmppReq();
|
||||
packet.setReq(req);
|
||||
packet.setTo("juliet@capulet.com/balcony");
|
||||
packet.setType(IQ.Type.SET);
|
||||
packet.setPacketID("42");
|
||||
|
||||
<font color="#3f7f5f">// send it</font>
|
||||
connection.sendPacket(packet);
|
||||
|
||||
|
||||
<font color="#3f7f5f">// then in your PacketListener</font>
|
||||
private class IqPacketListener implements PacketListener {
|
||||
|
||||
@Override
|
||||
public void processPacket(Packet packet) {
|
||||
IQ iq = (IQ) packet;
|
||||
|
||||
<font color="#3f7f5f">// verify from and packed ID</font>
|
||||
if (iq.getFrom().equals("juliet@capulet.com/balcony") && (iq.getPacketID().equals("42"))) {
|
||||
|
||||
<font color="#3f7f5f">// ensure it's not ERROR</font>
|
||||
if (iq.getType().equals(IQ.Type.RESULT)) {
|
||||
|
||||
<font color="#3f7f5f">// check if correct IQ implementation arrived</font>
|
||||
if (iq instanceof HttpOverXmppResp) {
|
||||
HttpOverXmppResp resp = (HttpOverXmppResp) iq;
|
||||
|
||||
<font color="#3f7f5f">// check HTTP response code</font>
|
||||
if (resp.getResp().getStatusCode() == 200) {
|
||||
|
||||
<font color="#3f7f5f">// get content of the response</font>
|
||||
AbstractHttpOverXmpp.DataChild child = resp.getResp().getData().getChild();
|
||||
|
||||
<font color="#3f7f5f">// check which type of content of the response arrived</font>
|
||||
if (child instanceof AbstractHttpOverXmpp.Xml) {
|
||||
|
||||
<font color="#3f7f5f">// print the message and anxiously read if from console ;)</font>
|
||||
System.out.println(((AbstractHttpOverXmpp.Xml) child).getText());
|
||||
} else {
|
||||
<font color="#3f7f5f">// process other AbstractHttpOverXmpp.DataChild subtypes</font>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
137
documentation/extensions/hoxt.md
Normal file
137
documentation/extensions/hoxt.md
Normal file
|
@ -0,0 +1,137 @@
|
|||
HTTP over XMPP transport
|
||||
========================
|
||||
|
||||
Allows to transport 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 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
|
||||
DiscoverInfo discoInfo = discoManager.discoverInfo("juliet@capulet.com");
|
||||
// Check if room is HOXT is supported
|
||||
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 limitation of XMPP message
|
||||
size).
|
||||
|
||||
**Usage**
|
||||
|
||||
First you need to register a _**PacketListener**_ 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 _**PacketListener**_.
|
||||
For the HTTP server you:
|
||||
|
||||
* You handle the _**HttpOverXmppReq**_ requests in your _**PacketListener**_.
|
||||
* And create and send _**HttpOverXmppResp**_ responses.
|
||||
|
||||
**Examples**
|
||||
|
||||
In this example we are HTTP client, so we send request (POST) and handle the
|
||||
response:
|
||||
|
||||
```
|
||||
// register listener for IQ packets
|
||||
connection.addPacketListener(new IqPacketListener(), new PacketTypeFilter(IQ.class));
|
||||
// create a request body
|
||||
String urlEncodedMessage = "I_love_you";
|
||||
|
||||
// create request
|
||||
HttpOverXmppReq.Req req = new HttpOverXmppReq.Req(HttpMethod.POST, "/mailbox");
|
||||
req.setVersion("1.1");
|
||||
|
||||
// prepare headers
|
||||
Set<Header> set = new HashSet<Header>();
|
||||
set.add(new Header("Host", "juliet.capulet.com"));
|
||||
set.add(new Header("Content-Type", "application/x-www-form- urlencoded"));
|
||||
set.add(new Header("Content-Length", Integer.toString(urlEncodedMessage.length())));
|
||||
req.setHeaders(new HeadersExtension(set));
|
||||
|
||||
// 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);
|
||||
req.setData(data);
|
||||
|
||||
// create IQ packet
|
||||
HttpOverXmppReq packet = new HttpOverXmppReq();
|
||||
packet.setReq(req);
|
||||
packet.setTo("juliet@capulet.com/balcony");
|
||||
packet.setType(IQ.Type.SET);
|
||||
packet.setPacketID("42");
|
||||
|
||||
// send it
|
||||
connection.sendPacket(packet);
|
||||
|
||||
|
||||
// then in your PacketListener
|
||||
private class IqPacketListener implements PacketListener {
|
||||
|
||||
@Override
|
||||
public void processPacket(Packet packet) {
|
||||
IQ iq = (IQ) packet;
|
||||
|
||||
// verify from and packed ID
|
||||
if (iq.getFrom().equals("juliet@capulet.com/balcony") && (iq.getPacketID().equals("42"))) {
|
||||
|
||||
// ensure it's not ERROR
|
||||
if (iq.getType().equals(IQ.Type.RESULT)) {
|
||||
|
||||
// check if correct IQ implementation arrived
|
||||
if (iq instanceof HttpOverXmppResp) {
|
||||
HttpOverXmppResp resp = (HttpOverXmppResp) iq;
|
||||
|
||||
// check HTTP response code
|
||||
if (resp.getResp().getStatusCode() == 200) {
|
||||
|
||||
// get content of the response
|
||||
AbstractHttpOverXmpp.DataChild child = resp.getResp().getData().getChild();
|
||||
|
||||
// check which type of content of the response arrived
|
||||
if (child instanceof AbstractHttpOverXmpp.Xml) {
|
||||
|
||||
// print the message and anxiously read if from console ;)
|
||||
System.out.println(((AbstractHttpOverXmpp.Xml) child).getText());
|
||||
} else {
|
||||
// process other AbstractHttpOverXmpp.DataChild subtypes
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
|
@ -1,15 +0,0 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Smack Extensions User Manual</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
</head>
|
||||
|
||||
<frameset cols="200,*">
|
||||
<frame src="toc.html" name="navFrame" target="mainFrame">
|
||||
<frame src="intro.html" name="mainFrame">
|
||||
</frameset>
|
||||
<noframes>
|
||||
<H2>Smack Extensions User Manual</H2>
|
||||
|
||||
<a href="toc.html">Smack Extensions User Manual</a></noframes></html>
|
70
documentation/extensions/index.md
Normal file
70
documentation/extensions/index.md
Normal file
|
@ -0,0 +1,70 @@
|
|||
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.
|
||||
|
||||
Smack Extensions and currently supported XEPs by Smack (smack-extensions)
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
| Name | XEP | Description |
|
||||
|---------------------------------------------|----------------------------------------------------------|----------------------------------------------------------------------------------------------------------|
|
||||
| [Data Forms](dataforms.html) | [XEP-0004](http://xmpp.org/extensions/xep-0004.html) | Allows to gather data using Forms. |
|
||||
| Last Activity | [XEP-0012](http://xmpp.org/extensions/xep-0012.html) | Communicating information about the last activity associated with an XMPP entity. |
|
||||
| Flexible Offline Message Retrieval | [XEP-0013](http://xmpp.org/extensions/xep-0013.html) | Extension for flexible, POP3-like handling of offline messages. |
|
||||
| [Privacy Lists](privacy.html) | [XEP-0016](http://xmpp.org/extensions/xep-0016.html) | Enabling or disabling communication with other entities. |
|
||||
| [Message Events](messageevents.html) | [XEP-0022](http://xmpp.org/extensions/xep-0022.html) | Requests and responds to message events. |
|
||||
| [Service Discovery](disco.html) | [XEP-0030](http://xmpp.org/extensions/xep-0030.html) | Allows to discover services in XMPP entities. |
|
||||
| Extended Stanza Addressing | [XEP-0033](http://xmpp.org/extensions/xep-0033.html) | Allows to include headers in stanzas in order to specifiy multiple recipients or sub-addresses. |
|
||||
| [Multi User Chat](muc.html) | [XEP-0045](http://xmpp.org/extensions/xep-0045.html) | Allows configuration of, participation in, and administration of individual text-based conference rooms. |
|
||||
| In-Band Bytestreams | [XEP-0047](http://xmpp.org/extensions/xep-0047.html) | Enables any two entities to establish a one-to-one bytestream between themselves using plain XMPP. |
|
||||
| Bookmarks | [XEP-0048](http://xmpp.org/extensions/xep-0048.html) | Bookmarks, for e.g. MUC and web pages. |
|
||||
| [Private Data](privatedata.html) | [XEP-0049](http://xmpp.org/extensions/xep-0049.html) | Manages private data. |
|
||||
| Ad-Hoc Commands | [XEP-0050](http://xmpp.org/extensions/xep-0049.html) | Advertising and executing application-specific commands. |
|
||||
| vcard-temp | [XEP-0054](http://xmpp.org/extensions/xep-0049.html) | The vCard-XML format currently in use. |
|
||||
| Jabber Search | [XEP-0055](http://xmpp.org/extensions/xep-0055.html) | Search information repositories on the XMPP network. |
|
||||
| [PubSub](pubsub.html) | [XEP-0060](http://xmpp.org/extensions/xep-0060.html) | Generic publish and subscribe functionality. |
|
||||
| SOCKS5 Bytestrams | [XEP-0065](http://xmpp.org/extensions/xep-0065.html) | Out-of-band bytestream between any two XMPP entities. |
|
||||
| [XHTML-IM](xhtml.html) | [XEP-0071](http://xmpp.org/extensions/xep-0071.html) | Allows send and receiving formatted messages using XHTML. |
|
||||
| In-Band Registration | [XEP-0077](http://xmpp.org/extensions/xep-0077.html) | In-band registration with XMPP services. |
|
||||
| Advanced Message Processing | [XEP-0079](http://xmpp.org/extensions/xep-0079.html) | Enables entities to request, and servers to perform, advanced processing of XMPP message stanzas. |
|
||||
| XMPP Date Time Profiles | [XEP-0082](http://xmpp.org/extensions/xep-0082.html) | Standardization of Date and Time representation in XMPP. |
|
||||
| Chat State Notifications | [XEP-0085](http://xmpp.org/extensions/xep-0085.html) | Communicating the status of a user in a chat session. |
|
||||
| [Time Exchange](time.html) | [XEP-0090](http://xmpp.org/extensions/xep-0090.html) | Allows local time information to be shared between users. |
|
||||
| Software Version | [XEP-0092](http://xmpp.org/extensions/xep-0092.html) | Retrieve and announce the software application of an XMPP entity. |
|
||||
| Stream Initation | [XEP-0095](http://xmpp.org/extensions/xep-0095.html) | Initiating a data stream between any two XMPP entities. |
|
||||
| [SI File Transfer](filetransfer.html) | [XEP-0096](http://xmpp.org/extensions/xep-0096.html) | Transfer files between two users over XMPP. |
|
||||
| [Entity Capabilities](caps.html) | [XEP-0115](http://xmpp.org/extensions/xep-0115.html) | Broadcasting and dynamic discovery of entity capabilities. |
|
||||
| Stream Compression | [XEP-0138](http://xmpp.org/extensions/xep-0138.html) | Support for optional compression of the XMPP stream.
|
||||
| Personal Eventing Protocol | [XEP-0163](http://xmpp.org/extensions/xep-0163.html) | Using the XMPP publish-subscribe protocol to broadcast state change events associated with a XMPP account. |
|
||||
| Message Delivery Receipts | [XEP-0184](http://xmpp.org/extensions/xep-0184.html) | Extension for message delivery receipts. The sender can request notification that the message has been delivered. |
|
||||
| XMPP Ping | [XEP-0199](http://xmpp.org/extensions/xep-0199.html) | Sending application-level pings over XML streams.
|
||||
| Entity Time | [XEP-0202](http://xmpp.org/extensions/xep-0202.html) | Allows entities to communicate their local time |
|
||||
| Delayed Delivery | [XEP-0203](http://xmpp.org/extensions/xep-0203.html) | Extension for communicating the fact that an XML stanza has been delivered with a delay. |
|
||||
| XMPP Over BOSH | [XEP-0206](http://xmpp.org/extensions/xep-0206.html) | Use Bidirectional-streams Over Synchronous HTTP (BOSH) to transport XMPP stanzas. |
|
||||
| [Group Chat Invitations](invitation.html) | n/a | Send invitations to other users to join a group chat room. |
|
||||
| [Jive Properties](properties.html) | n/a | TODO |
|
||||
|
||||
|
||||
Experimental Smack Extensions and currently supported XEPs by Smack (smack-experimental)
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
| Name | XEP | Description |
|
||||
|---------------------------------------------|----------------------------------------------------------|----------------------------------------------------------------------------------------------------------|
|
||||
| Message Carbons | [XEP-0280](http://xmpp.org/extensions/xep-0280.html) | Keep all IM clients for a user engaged in a conversation, by carbon-copy outbound messages to all interested resources.
|
||||
| [HTTP over XMPP transport](hoxt.html) | [XEP-0332](http://xmpp.org/extensions/xep-0332.html) | Allows to transport HTTP communication over XMPP peer-to-peer networks. |
|
||||
|
||||
|
||||
Legacy Smack Extensions and currently supported XEPs by Smack (smack-legacy)
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
If a XEP becomes 'Deprecated' or 'Obsolete' the code will be moved to the *smack-legacy* subproject.
|
||||
|
||||
| Name | XEP | Description |
|
||||
|---------------------------------------------|----------------------------------------------------------|----------------------------------------------------------------------------------------------------------|
|
||||
| [Roster Item Exchange](rosterexchange.html) | [XEP-0093](http://xmpp.org/extensions/xep-0093.html) | Allows roster data to be shared between users. |
|
|
@ -1,100 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Smack Extensions User Manual</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="header">Smack Extensions Manual</div>
|
||||
<p>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.</p>
|
||||
|
||||
<p>This manual provides details about each of the "smackx" extensions, including what
|
||||
it is, how to use it, and some simple example code.<p>
|
||||
|
||||
<div class="subheader">Current Extensions</div><p>
|
||||
|
||||
<table border="0" width="85%" cellspacing="0" cellpadding="3" style="border:1px #bbb solid;">
|
||||
<tr bgcolor="#ddeeff">
|
||||
<td><b>Name</b></td><td><b>XEP #</b></td><td><b>Description</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="privatedata.html">Private Data</a></td>
|
||||
<td><a href="http://www.xmpp.org/extensions/xep-0049.html">XEP-0049</a></td>
|
||||
<td>Manages private data.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="xhtml.html">XHTML Messages</a></td>
|
||||
<td><a href="http://www.xmpp.org/extensions/xep-0071.html">XEP-0071</a></td>
|
||||
<td>Allows send and receiving formatted messages using XHTML.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="messageevents.html">Message Events</a></td>
|
||||
<td><a href="http://www.xmpp.org/extensions/xep-0022.html">XEP-0022</a></td>
|
||||
<td>Requests and responds to message events.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="dataforms.html">Data Forms</a></td>
|
||||
<td><a href="http://www.xmpp.org/extensions/xep-0004.html">XEP-0004</a></td>
|
||||
<td>Allows to gather data using Forms.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="muc.html">Multi User Chat</a></td>
|
||||
<td><a href="http://www.xmpp.org/extensions/xep-0045.html">XEP-0045</a></td>
|
||||
<td>Allows configuration of, participation in, and administration of individual text-based conference rooms.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="rosterexchange.html">Roster Item Exchange</a></td>
|
||||
<td><a href="http://www.xmpp.org/extensions/xep-0093.html">XEP-0093</a></td>
|
||||
<td>Allows roster data to be shared between users.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="time.html">Time Exchange</a></td>
|
||||
<td><a href="http://www.xmpp.org/extensions/xep-0090.html">XEP-0090</a></td>
|
||||
<td>Allows local time information to be shared between users.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="invitation.html">Group Chat Invitations</a></td>
|
||||
<td>N/A</td>
|
||||
<td>Send invitations to other users to join a group chat room.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="disco.html">Service Discovery</a></td>
|
||||
<td><a href="http://www.xmpp.org/extensions/xep-0030.html">XEP-0030</a></td>
|
||||
<td>Allows to discover services in XMPP entities.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="filetransfer.html">File Transfer</a></td>
|
||||
<td><a href="http://www.xmpp.org/extensions/xep-0096.html">XEP-0096</a></td>
|
||||
<td>Transfer files between two users over XMPP.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="pubsub.html">PubSub</a></td>
|
||||
<td><a href="http://www.xmpp.org/extensions/xep-0060.html">XEP-0060</a></td>
|
||||
<td>Generic publish and subscribe functionality.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="caps.html">Entity Capabilities</a></td>
|
||||
<td><a href="http://www.xmpp.org/extensions/xep-0115.html">XEP-0115</a></td>
|
||||
<td>Broadcasting and dynamic discovery of entity capabilities.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="privacy.html">Privacy Lists</a></td>
|
||||
<td><a href="http://www.xmpp.org/extensions/xep-0016.html">XEP-0016</a></td>
|
||||
<td>Enabling or disabling communication with other entities.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="hoxt.html">HTTP over XMPP transport</a></td>
|
||||
<td><a href="http://www.xmpp.org/extensions/xep-0332.html">XEP-0332</a></td>
|
||||
<td>Allows to transport HTTP communication over XMPP peer-to-peer networks.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="properties.html">Jive Properties</a></td>
|
||||
<td>N/A</td>
|
||||
<td>TODO</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
99
documentation/extensions/intro.md
Normal file
99
documentation/extensions/intro.md
Normal file
|
@ -0,0 +1,99 @@
|
|||
Smack Extensions Manual
|
||||
|
||||
Current Extensions
|
||||
|
||||
**Name**
|
||||
**XEP #**
|
||||
**Description**
|
||||
|
||||
[Private Data](privatedata.html)
|
||||
|
||||
[XEP-0049](http://www.xmpp.org/extensions/xep-0049.html)
|
||||
|
||||
Manages private data.
|
||||
|
||||
[XHTML Messages](xhtml.html)
|
||||
|
||||
[XEP-0071](http://www.xmpp.org/extensions/xep-0071.html)
|
||||
|
||||
Allows send and receiving formatted messages using XHTML.
|
||||
|
||||
[Message Events](messageevents.html)
|
||||
|
||||
[XEP-0022](http://www.xmpp.org/extensions/xep-0022.html)
|
||||
|
||||
Requests and responds to message events.
|
||||
|
||||
[Data Forms](dataforms.html)
|
||||
|
||||
[XEP-0004](http://www.xmpp.org/extensions/xep-0004.html)
|
||||
|
||||
Allows to gather data using Forms.
|
||||
|
||||
[Multi User Chat](muc.html)
|
||||
|
||||
[XEP-0045](http://www.xmpp.org/extensions/xep-0045.html)
|
||||
|
||||
Allows configuration of, participation in, and administration of individual
|
||||
text-based conference rooms.
|
||||
|
||||
[Roster Item Exchange](rosterexchange.html)
|
||||
|
||||
[XEP-0093](http://www.xmpp.org/extensions/xep-0093.html)
|
||||
|
||||
Allows roster data to be shared between users.
|
||||
|
||||
[Time Exchange](time.html)
|
||||
|
||||
[XEP-0090](http://www.xmpp.org/extensions/xep-0090.html)
|
||||
|
||||
Allows local time information to be shared between users.
|
||||
|
||||
[Group Chat Invitations](invitation.html)
|
||||
|
||||
N/A
|
||||
|
||||
Send invitations to other users to join a group chat room.
|
||||
|
||||
[Service Discovery](disco.html)
|
||||
|
||||
[XEP-0030](http://www.xmpp.org/extensions/xep-0030.html)
|
||||
|
||||
Allows to discover services in XMPP entities.
|
||||
|
||||
[File Transfer](filetransfer.html)
|
||||
|
||||
[XEP-0096](http://www.xmpp.org/extensions/xep-0096.html)
|
||||
|
||||
Transfer files between two users over XMPP.
|
||||
|
||||
[PubSub](pubsub.html)
|
||||
|
||||
[XEP-0060](http://www.xmpp.org/extensions/xep-0060.html)
|
||||
|
||||
Generic publish and subscribe functionality.
|
||||
|
||||
[Entity Capabilities](caps.html)
|
||||
|
||||
[XEP-0115](http://www.xmpp.org/extensions/xep-0115.html)
|
||||
|
||||
Broadcasting and dynamic discovery of entity capabilities.
|
||||
|
||||
[Privacy Lists](privacy.html)
|
||||
|
||||
[XEP-0016](http://www.xmpp.org/extensions/xep-0016.html)
|
||||
|
||||
Enabling or disabling communication with other entities.
|
||||
|
||||
[HTTP over XMPP transport](hoxt.html)
|
||||
|
||||
[XEP-0332](http://www.xmpp.org/extensions/xep-0332.html)
|
||||
|
||||
Allows to transport HTTP communication over XMPP peer-to-peer networks.
|
||||
|
||||
[Jive Properties](properties.html)
|
||||
|
||||
N/A
|
||||
|
||||
TODO
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Group Chat Invitations</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="header">Group Chat Invitations</div><p>
|
||||
|
||||
The group chat invitation packet extension is used to invite other
|
||||
users to a group chat room.
|
||||
|
||||
<ul>
|
||||
<li><a href="#send">Inviting Other Users</a></li>
|
||||
<li><a href="#listen">Listen for Invitations</a></li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
<b>XEP related:</b> N/A -- this protocol is outdated now that the Multi-User Chat (MUC) XEP is available
|
||||
(<a href="http://www.xmpp.org/extensions/xep-0045.html">XEP-45</a>). However, most
|
||||
existing clients still use this older protocol. Once MUC support becomes more
|
||||
widespread, this API may be deprecated.
|
||||
|
||||
<hr>
|
||||
|
||||
<p><div class="subheader"><a name="send">Inviting Other Users</a></div><p>
|
||||
|
||||
To use the GroupChatInvitation packet extension
|
||||
to invite another user to a group chat room, address a new message to the
|
||||
user and set the room name appropriately, as in the following code example:
|
||||
|
||||
<pre>
|
||||
Message message = new Message(<font color="#0000FF">"user@chat.example.com"</font>);
|
||||
message.setBody(<font color="#0000FF">"Join me for a group chat!"</font>);
|
||||
message.addExtension(new GroupChatInvitation(<font color="#0000FF">"room@chat.example.com"</font>));
|
||||
con.sendPacket(message);
|
||||
</pre>
|
||||
|
||||
The XML generated for the invitation portion of the code above would be:
|
||||
|
||||
<pre>
|
||||
<x xmlns="jabber:x:conference" jid="room@chat.example.com"/>
|
||||
</pre><p>
|
||||
|
||||
<hr>
|
||||
<div class="subheader"><a name="listen">Listening for Invitations</a></div><p>
|
||||
|
||||
To listen for group chat invitations, use a PacketExtensionFilter for the
|
||||
<tt>x</tt> element name and <tt>jabber:x:conference</tt> namespace, as in the
|
||||
following code example:
|
||||
|
||||
<pre>
|
||||
PacketFilter filter = new PacketExtensionFilter(<font color="#0000FF">"x"</font>, <font color="#0000FF">"jabber:x:conference"</font>);
|
||||
<font color="#3f7f5f">// Create a packet collector or packet listeners using the filter...</font>
|
||||
</pre>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
42
documentation/extensions/invitation.md
Normal file
42
documentation/extensions/invitation.md
Normal file
|
@ -0,0 +1,42 @@
|
|||
Group Chat Invitations
|
||||
======================
|
||||
|
||||
The group chat invitation packet extension is used to invite other users to a
|
||||
group chat room.
|
||||
|
||||
* Inviting Other Users
|
||||
* Listen for Invitations
|
||||
|
||||
**XEP related:** N/A -- this protocol is outdated now that the Multi-User Chat (MUC) XEP is available ([XEP-45](http://www.xmpp.org/extensions/xep-0045.html)). However, most existing clients still use this older protocol. Once MUC support becomes more widespread, this API may be deprecated.
|
||||
|
||||
Inviting Other Users
|
||||
--------------------
|
||||
|
||||
To use the GroupChatInvitation packet extension to invite another user to a
|
||||
group chat room, address a new message to the user and set the room name
|
||||
appropriately, as in the following code example:
|
||||
|
||||
```
|
||||
Message message = new Message("user@chat.example.com");
|
||||
message.setBody("Join me for a group chat!");
|
||||
message.addExtension(new GroupChatInvitation("room@chat.example.com"));
|
||||
con.sendPacket(message);
|
||||
```
|
||||
|
||||
The XML generated for the invitation portion of the code above would be:
|
||||
|
||||
```
|
||||
<x xmlns="jabber:x:conference" jid="room@chat.example.com"/>
|
||||
```
|
||||
|
||||
Listening for Invitations
|
||||
-------------------------
|
||||
|
||||
To listen for group chat invitations, use a PacketExtensionFilter for the `x`
|
||||
element name and `jabber:x:conference` namespace, as in the following code
|
||||
example:
|
||||
|
||||
```
|
||||
PacketFilter filter = new PacketExtensionFilter("x", "jabber:x:conference");
|
||||
// Create a packet collector or packet listeners using the filter...
|
||||
```
|
|
@ -1,244 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Message Events</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="header">Message Events</div><p>
|
||||
|
||||
This extension is used to request and respond to events relating to the delivery,
|
||||
display, and composition of messages. There are three stages in this extension:<ol>
|
||||
<li>Request for event notifications,
|
||||
<li>Receive the event notification requests and send event notifications, and
|
||||
<li>Receive the event notifications.</ol>
|
||||
<p>For more information on each stage please follow these links:</p>
|
||||
<ul>
|
||||
<li><a href="#reqevnot">Requesting Event Notifications</a></li>
|
||||
<li><a href="#lstevnotreq">Reacting to Event Notification Requests</a></li>
|
||||
<li><a href="#lstevnot">Reacting to Event Notifications</a></li>
|
||||
</ul>
|
||||
<b>XEP related:</b> <a href="http://www.xmpp.org/extensions/xep-0022.html">XEP-22</a>
|
||||
<hr>
|
||||
<div class="subheader"><a name="reqevnot">Requesting Event Notifications</a></div><p>
|
||||
<b>Description</b><p>
|
||||
|
||||
In order to receive event notifications for a given message you first have to specify
|
||||
which events are you interested in. Each message that you send has to request its own event
|
||||
notifications. Therefore, every message that you send as part of a chat should request its own event
|
||||
notifications.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
The class <i>MessageEventManager</i> provides an easy way for requesting event notifications. All you have to do is specify
|
||||
the message that requires the event notifications and the events that you are interested in.
|
||||
<p>Use the static method <i><b>MessageEventManager.addNotificationsRequests(Message message, boolean offline, boolean
|
||||
delivered, boolean displayed, boolean composing)</b></i> for requesting event notifications.
|
||||
</p>
|
||||
|
||||
<b>Example</b><p>
|
||||
Below you can find an example that logs in a user to the server, creates a message, adds the requests
|
||||
for notifications and sends the message.
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Connect to the server and log in</font>
|
||||
conn1 = new XMPPConnection(host);
|
||||
conn1.login(server_user1, pass1);
|
||||
|
||||
<font color="#3f7f5f">// Create a chat with user2</font>
|
||||
Chat chat1 = conn1.createChat(user2);
|
||||
|
||||
<font color="#3f7f5f">// Create a message to send</font>
|
||||
Message msg = chat1.createMessage();
|
||||
msg.setSubject(<font color="#0000FF">"Any subject you want"</font>);
|
||||
msg.setBody(<font color="#0000FF">"An interesting body comes here..."</font>);
|
||||
<font color="#3f7f5f">// Add to the message all the notifications requests (offline, delivered, displayed,</font>
|
||||
<font color="#3f7f5f">// composing)</font>
|
||||
MessageEventManager.addNotificationsRequests(msg, <font COLOR="#7f0055"><b>true</b></font>, <font COLOR="#7f0055"><b>true</b></font>, <font COLOR="#7f0055"><b>true</b></font>, <font COLOR="#7f0055"><b>true</b></font>);
|
||||
|
||||
<font color="#3f7f5f">// Send the message that contains the notifications request</font>
|
||||
chat1.sendMessage(msg);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="lstevnotreq">Reacting to Event Notification Requests</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
You can receive notification requests for the following events: delivered, displayed, composing and offline. You
|
||||
<b>must</b> listen for these requests and react accordingly.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
The general idea is to create a new <i>DefaultMessageEventRequestListener</i> that will listen to the event notifications
|
||||
requests and react with custom logic. Then you will have to add the listener to the
|
||||
<i>MessageEventManager</i> that works on
|
||||
the desired <i>XMPPConnection</i>.
|
||||
<p>Note that <i>DefaultMessageEventRequestListener</i> is a default implementation of the
|
||||
<i>MessageEventRequestListener</i> interface.
|
||||
The class <i>DefaultMessageEventRequestListener</i> automatically sends a delivered notification to the sender of the message
|
||||
if the sender has requested to be notified when the message is delivered. If you decide to create a new class that
|
||||
implements the <i>MessageEventRequestListener</i> interface, please remember to send the delivered notification.</p>
|
||||
<ul>
|
||||
<li>To create a new <i>MessageEventManager</i> use the <i><b>MessageEventManager(XMPPConnection)</b></i> constructor.
|
||||
</li>
|
||||
<li>To create an event notification requests listener create a subclass of <i><b>DefaultMessageEventRequestListener</b></i> or
|
||||
create a class that implements the <i><b>MessageEventRequestListener</b></i> interface.
|
||||
</li>
|
||||
<li>To add a listener to the messageEventManager use the MessageEventManager's message
|
||||
<i><b>addMessageEventRequestListener(MessageEventRequestListener)</b></i>.</li>
|
||||
</ul></p>
|
||||
|
||||
<b>Example</b><p>
|
||||
|
||||
Below you can find an example that connects two users to the server. One user will create a message, add the requests
|
||||
for notifications and will send the message to the other user. The other user will add a
|
||||
<i>DefaultMessageEventRequestListener</i>
|
||||
to a <i>MessageEventManager</i> that will listen and react to the event notification requested by the other user.
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Connect to the server and log in the users</font>
|
||||
conn1 = new XMPPConnection(host);
|
||||
conn1.login(server_user1, pass1);
|
||||
conn2 = new XMPPConnection(host);
|
||||
conn2.login(server_user2, pass2);
|
||||
|
||||
<font color="#3f7f5f">// User2 creates a MessageEventManager</font>
|
||||
MessageEventManager messageEventManager = new MessageEventManager(conn2);
|
||||
<font color="#3f7f5f">// User2 adds the listener that will react to the event notifications requests</font>
|
||||
messageEventManager.addMessageEventRequestListener(new DefaultMessageEventRequestListener() {
|
||||
public void deliveredNotificationRequested(
|
||||
String from,
|
||||
String packetID,
|
||||
MessageEventManager messageEventManager) {
|
||||
super.deliveredNotificationRequested(from, packetID, messageEventManager);
|
||||
<font color="#3f7f5f">// DefaultMessageEventRequestListener automatically responds that the message was delivered when receives this request</font>
|
||||
System.out.println(<font color="#0000FF">"Delivered Notification Requested (" + from + ", " + packetID + ")"</font>);
|
||||
}
|
||||
|
||||
public void displayedNotificationRequested(
|
||||
String from,
|
||||
String packetID,
|
||||
MessageEventManager messageEventManager) {
|
||||
super.displayedNotificationRequested(from, packetID, messageEventManager);
|
||||
<font color="#3f7f5f">// Send to the message's sender that the message was displayed</font>
|
||||
messageEventManager.sendDisplayedNotification(from, packetID);
|
||||
}
|
||||
|
||||
public void composingNotificationRequested(
|
||||
String from,
|
||||
String packetID,
|
||||
MessageEventManager messageEventManager) {
|
||||
super.composingNotificationRequested(from, packetID, messageEventManager);
|
||||
<font color="#3f7f5f">// Send to the message's sender that the message's receiver is composing a reply</font>
|
||||
messageEventManager.sendComposingNotification(from, packetID);
|
||||
}
|
||||
|
||||
public void offlineNotificationRequested(
|
||||
String from,
|
||||
String packetID,
|
||||
MessageEventManager messageEventManager) {
|
||||
super.offlineNotificationRequested(from, packetID, messageEventManager);
|
||||
<font color="#3f7f5f">// The XMPP server should take care of this request. Do nothing.</font>
|
||||
System.out.println(<font color="#0000FF">"Offline Notification Requested (" + from + ", " + packetID + ")"</font>);
|
||||
}
|
||||
});
|
||||
|
||||
<font color="#3f7f5f">// User1 creates a chat with user2</font>
|
||||
Chat chat1 = conn1.createChat(user2);
|
||||
|
||||
<font color="#3f7f5f">// User1 creates a message to send to user2</font>
|
||||
Message msg = chat1.createMessage();
|
||||
msg.setSubject(<font color="#0000FF">"Any subject you want"</font>);
|
||||
msg.setBody(<font color="#0000FF">"An interesting body comes here..."</font>);
|
||||
<font color="#3f7f5f">// User1 adds to the message all the notifications requests (offline, delivered, displayed,</font>
|
||||
<font color="#3f7f5f">// composing)</font>
|
||||
MessageEventManager.addNotificationsRequests(msg, <font COLOR="#7f0055"><b>true</b></font>, <font COLOR="#7f0055"><b>true</b></font>, <font COLOR="#7f0055"><b>true</b></font>, <font COLOR="#7f0055"><b>true</b></font>);
|
||||
|
||||
<font color="#3f7f5f">// User1 sends the message that contains the notifications request</font>
|
||||
chat1.sendMessage(msg);
|
||||
Thread.sleep(500);
|
||||
<font color="#3f7f5f">// User2 sends to the message's sender that the message's receiver cancelled composing a reply</font>
|
||||
messageEventManager.sendCancelledNotification(user1, msg.getPacketID());
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="lstevnot">Reacting to Event Notifications</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
Once you have requested for event notifications you will start to receive notifications of events. You can
|
||||
receive notifications of the following events: delivered, displayed, composing, offline and cancelled. You
|
||||
will probably want to react to some or all of these events.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
The general idea is to create a new <i>MessageEventNotificationListener</i> that will listen to the event notifications
|
||||
and react with custom logic. Then you will have to add the listener to the <i>MessageEventManager</i> that works on
|
||||
the desired <i>XMPPConnection</i>.
|
||||
<ul>
|
||||
<li>To create a new <i>MessageEventManager</i> use the <i><b>MessageEventManager(XMPPConnection)</b></i> constructor.
|
||||
</li>
|
||||
<li>To create an event notifications listener create a class that implements the <i><b>MessageEventNotificationListener</b></i>
|
||||
interface.
|
||||
</li>
|
||||
<li>To add a listener to the messageEventManager use the MessageEventManager's message
|
||||
<i><b>addMessageEventNotificationListener(MessageEventNotificationListener)</b></i>.</li>
|
||||
</ul></p>
|
||||
|
||||
<b>Example</b><p>
|
||||
Below you can find an example that logs in a user to the server, adds a <i>MessageEventNotificationListener</i>
|
||||
to a <i>MessageEventManager</i> that will listen and react to the event notifications, creates a message, adds
|
||||
the requests for notifications and sends the message.
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Connect to the server and log in</font>
|
||||
conn1 = new XMPPConnection(host);
|
||||
conn1.login(server_user1, pass1);
|
||||
|
||||
<font color="#3f7f5f">// Create a MessageEventManager</font>
|
||||
MessageEventManager messageEventManager = new MessageEventManager(conn1);
|
||||
<font color="#3f7f5f">// Add the listener that will react to the event notifications</font>
|
||||
messageEventManager.addMessageEventNotificationListener(new MessageEventNotificationListener() {
|
||||
public void deliveredNotification(String from, String packetID) {
|
||||
System.out.println(<font color="#0000FF">"The message has been delivered (" + from + ", " + packetID + ")"</font>);
|
||||
}
|
||||
|
||||
public void displayedNotification(String from, String packetID) {
|
||||
System.out.println(<font color="#0000FF">"The message has been displayed (" + from + ", " + packetID + ")"</font>);
|
||||
}
|
||||
|
||||
public void composingNotification(String from, String packetID) {
|
||||
System.out.println(<font color="#0000FF">"The message's receiver is composing a reply (" + from + ", " + packetID + ")"</font>);
|
||||
}
|
||||
|
||||
public void offlineNotification(String from, String packetID) {
|
||||
System.out.println(<font color="#0000FF">"The message's receiver is offline (" + from + ", " + packetID + ")"</font>);
|
||||
}
|
||||
|
||||
public void cancelledNotification(String from, String packetID) {
|
||||
System.out.println(<font color="#0000FF">"The message's receiver cancelled composing a reply (" + from + ", " + packetID + ")"</font>);
|
||||
}
|
||||
});
|
||||
|
||||
<font color="#3f7f5f">// Create a chat with user2</font>
|
||||
Chat chat1 = conn1.createChat(user2);
|
||||
|
||||
<font color="#3f7f5f">// Create a message to send</font>
|
||||
Message msg = chat1.createMessage();
|
||||
msg.setSubject(<font color="#0000FF">"Any subject you want"</font>);
|
||||
msg.setBody(<font color="#0000FF">"An interesting body comes here..."</font>);
|
||||
<font color="#3f7f5f">// Add to the message all the notifications requests (offline, delivered, displayed,</font>
|
||||
<font color="#3f7f5f">// composing)</font>
|
||||
MessageEventManager.addNotificationsRequests(msg, <font COLOR="#7f0055"><b>true</b></font>, <font COLOR="#7f0055"><b>true</b></font>, <font COLOR="#7f0055"><b>true</b></font>, <font COLOR="#7f0055"><b>true</b></font>);
|
||||
|
||||
<font color="#3f7f5f">// Send the message that contains the notifications request</font>
|
||||
chat1.sendMessage(msg);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
205
documentation/extensions/messageevents.md
Normal file
205
documentation/extensions/messageevents.md
Normal file
|
@ -0,0 +1,205 @@
|
|||
Message Events
|
||||
==============
|
||||
|
||||
This extension is used to request and respond to events relating to the
|
||||
delivery, display, and composition of messages. There are three stages in this
|
||||
extension:
|
||||
|
||||
1. Request for event notifications,
|
||||
2. Receive the event notification requests and send event notifications, and
|
||||
3. Receive the event notifications.
|
||||
|
||||
**XEP related:** [XEP-22](http://www.xmpp.org/extensions/xep-0022.html)
|
||||
|
||||
Requesting Event Notifications
|
||||
------------------------------
|
||||
|
||||
**Description**
|
||||
|
||||
In order to receive event notifications for a given message you first have to
|
||||
specify which events are you interested in. Each message that you send has to
|
||||
request its own event notifications. Therefore, every message that you send as
|
||||
part of a chat should request its own event notifications.
|
||||
|
||||
**Usage**
|
||||
|
||||
The class _MessageEventManager_ provides an easy way for requesting event
|
||||
notifications. All you have to do is specify the message that requires the
|
||||
event notifications and the events that you are interested in.
|
||||
|
||||
Use the static method _**MessageEventManager.addNotificationsRequests(Message
|
||||
message, boolean offline, boolean delivered, boolean displayed, boolean
|
||||
composing)**_ for requesting event notifications.
|
||||
|
||||
**Example**
|
||||
|
||||
Below you can find an example that logs in a user to the server, creates a
|
||||
message, adds the requests for notifications and sends the message.
|
||||
|
||||
```
|
||||
// Connect to the server and log in
|
||||
conn1 = new XMPPConnection(host);
|
||||
conn1.login(server_user1, pass1);
|
||||
// Create a chat with user2
|
||||
Chat chat1 = conn1.createChat(user2);
|
||||
// Create a message to send
|
||||
Message msg = chat1.createMessage();
|
||||
msg.setSubject("Any subject you want");
|
||||
msg.setBody("An interesting body comes here...");
|
||||
// Add to the message all the notifications requests (offline,
|
||||
// composing)
|
||||
MessageEventManager.addNotificationsRequests(msg, **true**, **true**, **true**, **true**);
|
||||
// Send the message that contains the notifications request
|
||||
chat1.sendMessage(msg);
|
||||
```
|
||||
|
||||
Reacting to Event Notification Requests
|
||||
---------------------------------------
|
||||
|
||||
**Description**
|
||||
|
||||
You can receive notification requests for the following events: delivered,
|
||||
displayed, composing and offline. You **must** listen for these requests and
|
||||
react accordingly.
|
||||
|
||||
**Usage**
|
||||
|
||||
The general idea is to create a new _DefaultMessageEventRequestListener_ that
|
||||
will listen to the event notifications requests and react with custom logic.
|
||||
Then you will have to add the listener to the _MessageEventManager_ that works
|
||||
on the desired _XMPPConnection_.
|
||||
|
||||
Note that _DefaultMessageEventRequestListener_ is a default implementation of
|
||||
the _MessageEventRequestListener_ interface. The class
|
||||
_DefaultMessageEventRequestListener_ automatically sends a delivered
|
||||
notification to the sender of the message if the sender has requested to be
|
||||
notified when the message is delivered. If you decide to create a new class
|
||||
that implements the _MessageEventRequestListener_ interface, please remember
|
||||
to send the delivered notification.
|
||||
|
||||
* To create a new _MessageEventManager_ use the _**MessageEventManager(XMPPConnection)**_ constructor.
|
||||
* To create an event notification requests listener create a subclass of _**DefaultMessageEventRequestListener**_ or create a class that implements the _**MessageEventRequestListener**_ interface.
|
||||
* To add a listener to the messageEventManager use the MessageEventManager's message _**addMessageEventRequestListener(MessageEventRequestListener)**_.
|
||||
|
||||
**Example**
|
||||
|
||||
Below you can find an example that connects two users to the server. One user
|
||||
will create a message, add the requests for notifications and will send the
|
||||
message to the other user. The other user will add a
|
||||
_DefaultMessageEventRequestListener_ to a _MessageEventManager_ that will
|
||||
listen and react to the event notification requested by the other user.
|
||||
|
||||
```
|
||||
// Connect to the server and log in the users
|
||||
conn1 = new XMPPConnection(host);
|
||||
conn1.login(server_user1, pass1);
|
||||
conn2 = new XMPPConnection(host);
|
||||
conn2.login(server_user2, pass2);
|
||||
// User2 creates a MessageEventManager
|
||||
MessageEventManager messageEventManager = new MessageEventManager(conn2);
|
||||
// User2 adds the listener that will react to the event notifications requests
|
||||
messageEventManager.addMessageEventRequestListener(new DefaultMessageEventRequestListener() {
|
||||
public void deliveredNotificationRequested(
|
||||
String from,
|
||||
String packetID,
|
||||
MessageEventManager messageEventManager) {
|
||||
super.deliveredNotificationRequested(from, packetID, messageEventManager);
|
||||
// DefaultMessageEventRequestListener automatically responds that the message was delivered when receives this r
|
||||
System.out.println("Delivered Notification Requested (" + from + ", " + packetID + ")");
|
||||
}
|
||||
public void displayedNotificationRequested(String from, String packetID, MessageEventManager messageEventManager) {
|
||||
super.displayedNotificationRequested(from, packetID,
|
||||
// Send to the message's sender that the message was
|
||||
messageEventManager.sendDisplayedNotification(from, packetID);
|
||||
}
|
||||
public void composingNotificationRequested(String from, String packetID, MessageEventManager messageEventManager) {
|
||||
super.composingNotificationRequested(from, packetID, messageEventManager);
|
||||
// Send to the message's sender that the message's receiver is composing a reply
|
||||
messageEventManager.sendComposingNotification(from, packetID);
|
||||
}
|
||||
public void offlineNotificationRequested(String from, String packetID, MessageEventManager messageEventManager) {
|
||||
super.offlineNotificationRequested(from, packetID, messageEventManager);
|
||||
// The XMPP server should take care of this request. Do nothing.
|
||||
System.out.println("Offline Notification Requested (" + from + ", " + packetID + ")");
|
||||
}
|
||||
});
|
||||
// User1 creates a chat with user2
|
||||
Chat chat1 = conn1.createChat(user2);
|
||||
// User1 creates a message to send to user2
|
||||
Message msg = chat1.createMessage();
|
||||
msg.setSubject("Any subject you want");
|
||||
msg.setBody("An interesting body comes here...");
|
||||
// User1 adds to the message all the notifications requests (offline, delivered, displayed,
|
||||
// composing)
|
||||
MessageEventManager.addNotificationsRequests(msg, true, true, true, true);
|
||||
// User1 sends the message that contains the notifications request
|
||||
chat1.sendMessage(msg);
|
||||
Thread.sleep(500);
|
||||
// User2 sends to the message's sender that the message's receiver cancelled composing a reply
|
||||
messageEventManager.sendCancelledNotification(user1, msg.getPacketID());
|
||||
```
|
||||
|
||||
Reacting to Event Notifications
|
||||
-------------------------------
|
||||
|
||||
**Description**
|
||||
|
||||
Once you have requested for event notifications you will start to receive
|
||||
notifications of events. You can receive notifications of the following
|
||||
events: delivered, displayed, composing, offline and cancelled. You will
|
||||
probably want to react to some or all of these events.
|
||||
|
||||
**Usage**
|
||||
|
||||
The general idea is to create a new _MessageEventNotificationListener_ that
|
||||
will listen to the event notifications and react with custom logic. Then you
|
||||
will have to add the listener to the _MessageEventManager_ that works on the
|
||||
desired _XMPPConnection_.
|
||||
|
||||
* To create a new _MessageEventManager_ use the _**MessageEventManager(XMPPConnection)**_ constructor.
|
||||
* To create an event notifications listener create a class that implements the _**MessageEventNotificationListener**_ interface.
|
||||
* To add a listener to the messageEventManager use the MessageEventManager's message _**addMessageEventNotificationListener(MessageEventNotificationListener)**_.
|
||||
|
||||
**Example**
|
||||
|
||||
Below you can find an example that logs in a user to the server, adds a
|
||||
_MessageEventNotificationListener_ to a _MessageEventManager_ that will listen
|
||||
and react to the event notifications, creates a message, adds the requests for
|
||||
notifications and sends the message.
|
||||
|
||||
```
|
||||
// Connect to the server and log in
|
||||
conn1 = new XMPPConnection(host);
|
||||
conn1.login(server_user1, pass1);
|
||||
// Create a MessageEventManager
|
||||
MessageEventManager messageEventManager = new MessageEventManager(conn1);
|
||||
// Add the listener that will react to the event notifications
|
||||
messageEventManager.addMessageEventNotificationListener(new MessageEventNotificationListener() {
|
||||
public void deliveredNotification(String from, String packetID) {
|
||||
System.out.println("The message has been delivered (" + from + ", " + packetID + ")");
|
||||
}
|
||||
public void displayedNotification(String from, String packetID) {
|
||||
System.out.println("The message has been displayed (" + from + ", " + packetID + ")");
|
||||
}
|
||||
public void composingNotification(String from, String packetID) {
|
||||
System.out.println("The message's receiver is composing a reply (" + from + ", " + packetID + ")");
|
||||
}
|
||||
public void offlineNotification(String from, String packetID) {
|
||||
System.out.println("The message's receiver is offline (" + from + ", " + packetID + ")");
|
||||
}
|
||||
public void cancelledNotification(String from, String packetID) {
|
||||
System.out.println("The message's receiver cancelled composing a reply (" + from + ", " + packetID + ")");
|
||||
}
|
||||
});
|
||||
// Create a chat with user2
|
||||
Chat chat1 = conn1.createChat(user2);
|
||||
// Create a message to send
|
||||
Message msg = chat1.createMessage();
|
||||
msg.setSubject("Any subject you want");
|
||||
msg.setBody("An interesting body comes here...");
|
||||
// Add to the message all the notifications requests (offline, delivered, displayed,
|
||||
// composing)
|
||||
MessageEventManager.addNotificationsRequests(msg, **true**, **true**, **true**, **true**);
|
||||
// Send the message that contains the notifications request
|
||||
chat1.sendMessage(msg);
|
||||
```
|
|
@ -1,619 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Multi User Chat</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="header">Multi User Chat</div><p>
|
||||
|
||||
Allows configuration of, participation in, and administration of individual text-based conference rooms.<p>
|
||||
|
||||
<ul>
|
||||
<li><a href="#create">Create a new Room</a></li>
|
||||
<li><a href="#join">Join a room</a></li>
|
||||
<li><a href="#invite">Manage room invitations</a></li>
|
||||
<li><a href="#discomuc">Discover MUC support</a></li>
|
||||
<li><a href="#discojoin">Discover joined rooms</a></li>
|
||||
<li><a href="#discoroom">Discover room information</a></li>
|
||||
<li><a href="#privchat">Start a private chat</a></li>
|
||||
<li><a href="#subject">Manage changes on room subject</a></li>
|
||||
<li><a href="#role">Manage role modifications</a></li>
|
||||
<li><a href="#afiliation">Manage affiliation modifications</a></li>
|
||||
</ul>
|
||||
<b>XEP related:</b> <a href="http://www.xmpp.org/extensions/xep-0045.html">XEP-45</a>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="create">Create a new Room</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
Allowed users may create new rooms. There are two types of rooms that you can create. <b>Instant rooms</b>
|
||||
which are available for immediate access and are automatically created based on some default
|
||||
configuration and <b>Reserved rooms</b> which are manually configured by the room creator before
|
||||
anyone is allowed to enter.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
In order to create a room you will need to first create an instance of <i><b>MultiUserChat</b></i>. The
|
||||
room name passed to the constructor will be the name of the room to create. The next step is to send
|
||||
<b>create(String nickname)</b> to the <i><b>MultiUserChat</b></i> instance where nickname is the nickname
|
||||
to use when joining the room.</p><p>
|
||||
|
||||
Depending on the type of room that you want to create you will have to use different configuration forms. In
|
||||
order to create an Instant room just send <b>sendConfigurationForm(Form form)</b> where form is an empty form.
|
||||
But if you want to create a Reserved room then you should first get the room's configuration form, complete
|
||||
the form and finally send it back to the server.</p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to create an instant room: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Create a MultiUserChat using a XMPPConnection for a room</font>
|
||||
MultiUserChat muc = new MultiUserChat(conn1, <font color="#0000FF">"myroom@conference.jabber.org"</font>);
|
||||
|
||||
<font color="#3f7f5f">// Create the room</font>
|
||||
muc.create(<font color="#0000FF">"testbot"</font>);
|
||||
|
||||
<font color="#3f7f5f">// Send an empty room configuration form which indicates that we want</font>
|
||||
<font color="#3f7f5f">// an instant room</font>
|
||||
muc.sendConfigurationForm(new Form(Form.TYPE_SUBMIT));
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
In this example we can see how to create a reserved room. The form is completed with default values: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Create a MultiUserChat using a XMPPConnection for a room</font>
|
||||
MultiUserChat muc = new MultiUserChat(conn1, <font color="#0000FF">"myroom@conference.jabber.org"</font>);
|
||||
|
||||
<font color="#3f7f5f">// Create the room</font>
|
||||
muc.create(<font color="#0000FF">"testbot"</font>);
|
||||
|
||||
<font color="#3f7f5f">// Get the the room's configuration form</font>
|
||||
Form form = muc.getConfigurationForm();
|
||||
<font color="#3f7f5f">// Create a new form to submit based on the original form</font>
|
||||
Form submitForm = form.createAnswerForm();
|
||||
<font color="#3f7f5f">// Add default answers to the form to submit</font>
|
||||
for (Iterator fields = form.getFields(); fields.hasNext();) {
|
||||
FormField field = (FormField) fields.next();
|
||||
if (!FormField.TYPE_HIDDEN.equals(field.getType()) && field.getVariable() != null) {
|
||||
<font color="#3f7f5f">// Sets the default value as the answer</font>
|
||||
submitForm.setDefaultAnswer(field.getVariable());
|
||||
}
|
||||
}
|
||||
<font color="#3f7f5f">// Sets the new owner of the room</font>
|
||||
List owners = new ArrayList();
|
||||
owners.add(<font color="#0000FF">"johndoe@jabber.org"</font>);
|
||||
submitForm.setAnswer(<font color="#0000FF">"muc#roomconfig_roomowners"</font>, owners);
|
||||
<font color="#3f7f5f">// Send the completed form (with default values) to the server to configure the room</font>
|
||||
muc.sendConfigurationForm(submitForm);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="join">Join a room</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
Your usual first step in order to send messages to a room is to join the room. Multi User Chat allows
|
||||
to specify several parameter while joining a room. Basically you can control the amount of history to
|
||||
receive after joining the room as well as provide your nickname within the room and a password if the
|
||||
room is password protected.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
In order to join a room you will need to first create an instance of <i><b>MultiUserChat</b></i>. The
|
||||
room name passed to the constructor will be the name of the room to join. The next step is to send
|
||||
<b>join(...)</b> to the <i><b>MultiUserChat</b></i> instance. But first you will have to decide which
|
||||
join message to send. If you want to just join the room without a password and without specifying the amount
|
||||
of history to receive then you could use <b>join(String nickname)</b> where nickname if your nickname in
|
||||
the room. In case the room requires a password in order to join you could then use
|
||||
<b>join(String nickname, String password)</b>. And finally, the most complete way to join a room is to send
|
||||
<b>join(String nickname, String password, DiscussionHistory history, long timeout)</b>
|
||||
where nickname is your nickname in the room, , password is your password to join the room, history is
|
||||
an object that specifies the amount of history to receive and timeout is the milliseconds to wait
|
||||
for a response from the server.</p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to join a room with a given nickname: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Create a MultiUserChat using a XMPPConnection for a room</font>
|
||||
MultiUserChat muc2 = new MultiUserChat(conn1, <font color="#0000FF">"myroom@conference.jabber.org"</font>);
|
||||
|
||||
<font color="#3f7f5f">// User2 joins the new room</font>
|
||||
<font color="#3f7f5f">// The room service will decide the amount of history to send</font>
|
||||
muc2.join(<font color="#0000FF">"testbot2"</font>);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
In this example we can see how to join a room with a given nickname and password: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Create a MultiUserChat using a XMPPConnection for a room</font>
|
||||
MultiUserChat muc2 = new MultiUserChat(conn1, <font color="#0000FF">"myroom@conference.jabber.org"</font>);
|
||||
|
||||
<font color="#3f7f5f">// User2 joins the new room using a password</font>
|
||||
<font color="#3f7f5f">// The room service will decide the amount of history to send</font>
|
||||
muc2.join(<font color="#0000FF">"testbot2"</font>, <font color="#0000FF">"password"</font>);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
In this example we can see how to join a room with a given nickname specifying the amount of history
|
||||
to receive: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Create a MultiUserChat using a XMPPConnection for a room</font>
|
||||
MultiUserChat muc2 = new MultiUserChat(conn1, <font color="#0000FF">"myroom@conference.jabber.org"</font>);
|
||||
|
||||
<font color="#3f7f5f">// User2 joins the new room using a password and specifying</font>
|
||||
<font color="#3f7f5f">// the amount of history to receive. In this example we are requesting the last 5 messages.</font>
|
||||
DiscussionHistory history = new DiscussionHistory();
|
||||
history.setMaxStanzas(5);
|
||||
muc2.join(<font color="#0000FF">"testbot2"</font>, <font color="#0000FF">"password"</font>, history, SmackConfiguration.getPacketReplyTimeout());
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="invite">Manage room invitations</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
It can be useful to invite another user to a room in which one is an occupant. Depending on the
|
||||
room's type the invitee could receive a password to use to join the room and/or be added to the
|
||||
member list if the room is of type members-only. Smack allows to send room invitations and let
|
||||
potential invitees to listening for room invitations and inviters to listen for invitees'
|
||||
rejections.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
In order to invite another user to a room you must be already joined to the room. Once you are
|
||||
joined just send <b>invite(String participant, String reason)</b> to the <i><b>MultiUserChat</b></i>
|
||||
where participant is the user to invite to the room (e.g. hecate@shakespeare.lit) and reason is
|
||||
the reason why the user is being invited.</p><p>
|
||||
|
||||
If potential invitees want to listen for room invitations then the invitee must add an <i><b>InvitationListener</b></i>
|
||||
to the <i><b>MultiUserChat</b></i> class. Since the <i><b>InvitationListener</b></i> is an <i>interface</i>,
|
||||
it is necessary to create a class that implements this <i>interface</i>. If an inviter wants to
|
||||
listen for room invitation rejections, just add an <i><b>InvitationRejectionListener</b></i>
|
||||
to the <i><b>MultiUserChat</b></i>. <i><b>InvitationRejectionListener</b></i> is also an
|
||||
interface so you will need to create a class that implements this interface.</p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to invite another user to the room and lister for possible rejections: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// User2 joins the room</font>
|
||||
MultiUserChat muc2 = new MultiUserChat(conn2, room);
|
||||
muc2.join(<font color="#0000FF">"testbot2"</font>);
|
||||
|
||||
<font color="#3f7f5f">// User2 listens for invitation rejections</font>
|
||||
muc2.addInvitationRejectionListener(new InvitationRejectionListener() {
|
||||
public void invitationDeclined(String invitee, String reason) {
|
||||
<font color="#3f7f5f">// Do whatever you need here...</font>
|
||||
}
|
||||
});
|
||||
|
||||
<font color="#3f7f5f">// User2 invites user3 to join to the room</font>
|
||||
muc2.invite(<font color="#0000FF">"user3@host.org/Smack"</font>, <font color="#0000FF">"Meet me in this excellent room"</font>);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
In this example we can see how to listen for room invitations and decline invitations: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// User3 listens for MUC invitations</font>
|
||||
MultiUserChat.addInvitationListener(conn3, new InvitationListener() {
|
||||
public void invitationReceived(XMPPConnection conn, String room, String inviter, String reason, String password) {
|
||||
<font color="#3f7f5f">// Reject the invitation</font>
|
||||
MultiUserChat.decline(conn, room, inviter, <font color="#0000FF">"I'm busy right now"</font>);
|
||||
}
|
||||
});
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="discomuc">Discover MUC support</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
A user may want to discover if one of the user's contacts supports the Multi-User Chat protocol.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
In order to discover if one of the user's contacts supports MUC just send
|
||||
<b>isServiceEnabled(XMPPConnection connection, String user)</b> to the <i><b>MultiUserChat</b></i>
|
||||
class where user is a fully qualified XMPP ID, e.g. jdoe@example.com. You will receive
|
||||
a boolean indicating whether the user supports MUC or not.</p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to discover support of MUC: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Discover whether user3@host.org supports MUC or not</font>
|
||||
boolean supports = MultiUserChat.isServiceEnabled(conn, <font color="#0000FF">"user3@host.org/Smack"</font>);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="discojoin">Discover joined rooms</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
A user may also want to query a contact regarding which rooms the contact is in.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
In order to get the rooms where a user is in just send
|
||||
<b>getJoinedRooms(XMPPConnection connection, String user)</b> to the <i><b>MultiUserChat</b></i>
|
||||
class where user is a fully qualified XMPP ID, e.g. jdoe@example.com. You will get an Iterator
|
||||
of Strings as an answer where each String represents a room name.</p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to get the rooms where a user is in: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Get the rooms where user3@host.org has joined</font>
|
||||
Iterator joinedRooms = MultiUserChat.getJoinedRooms(conn, <font color="#0000FF">"user3@host.org/Smack"</font>);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="discoroom">Discover room information</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
A user may need to discover information about a room without having to actually join the room. The server
|
||||
will provide information only for public rooms.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
In order to discover information about a room just send <b>getRoomInfo(XMPPConnection connection, String room)</b>
|
||||
to the <i><b>MultiUserChat</b></i> class where room is the XMPP ID of the room, e.g.
|
||||
roomName@conference.myserver. You will get a RoomInfo object that contains the discovered room
|
||||
information.</p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to discover information about a room: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Discover information about the room roomName@conference.myserver</font>
|
||||
RoomInfo info = MultiUserChat.getRoomInfo(conn, <font color="#0000FF">"roomName@conference.myserver"</font>);
|
||||
System.out.println("Number of occupants:" + info.getOccupantsCount());
|
||||
System.out.println("Room Subject:" + info.getSubject());
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="privchat">Start a private chat</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
A room occupant may want to start a private chat with another room occupant even though they
|
||||
don't know the fully qualified XMPP ID (e.g. jdoe@example.com) of each other.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
To create a private chat with another room occupant just send <b>createPrivateChat(String participant)</b>
|
||||
to the <i><b>MultiUserChat</b></i> that you used to join the room. The parameter participant is the
|
||||
occupant unique room JID (e.g. 'darkcave@macbeth.shakespeare.lit/Paul'). You will receive
|
||||
a regular <i><b>Chat</b></i> object that you can use to chat with the other room occupant.</p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to start a private chat with another room occupant: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Start a private chat with another participant</font>
|
||||
Chat chat = muc2.createPrivateChat(<font color="#0000FF">"myroom@conference.jabber.org/johndoe"</font>);
|
||||
chat.sendMessage(<font color="#0000FF">"Hello there"</font>);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="subject">Manage changes on room subject</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
A common feature of multi-user chat rooms is the ability to change the subject within the room. As a
|
||||
default, only users with a role of "moderator" are allowed to change the subject in a room. Although
|
||||
some rooms may be configured to allow a mere participant or even a visitor to change the subject.</p><p>
|
||||
|
||||
Every time the room's subject is changed you may want to be notified of the modification. The new subject
|
||||
could be used to display an in-room message.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
In order to modify the room's subject just send <b>changeSubject(String subject)</b> to the
|
||||
<i><b>MultiUserChat</b></i> that you used to join the room where subject is the new room's subject. On
|
||||
the other hand, if you want to be notified whenever the room's subject is modified you should add a
|
||||
<i><b>SubjectUpdatedListener</b></i> to the <i><b>MultiUserChat</b></i> by sending
|
||||
<b>addSubjectUpdatedListener(SubjectUpdatedListener listener)</b> to the <i><b>MultiUserChat</b></i>.
|
||||
Since the <i><b>SubjectUpdatedListener</b></i> is an <i>interface</i>, it is necessary to create a class
|
||||
that implements this <i>interface</i>.</p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to change the room's subject and react whenever the room's subject is
|
||||
modified: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// An occupant wants to be notified every time the room's subject is changed</font>
|
||||
muc3.addSubjectUpdatedListener(new SubjectUpdatedListener() {
|
||||
public void subjectUpdated(String subject, String from) {
|
||||
....
|
||||
}
|
||||
});
|
||||
|
||||
<font color="#3f7f5f">// A room's owner changes the room's subject</font>
|
||||
muc2.changeSubject(<font color="#0000FF">"New Subject"</font>);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="role">Manage role modifications</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
There are four defined roles that an occupant can have:</p>
|
||||
<ol start="" type="">
|
||||
<li>Moderator</li>
|
||||
<li>Participant</li>
|
||||
<li>Visitor</li>
|
||||
<li>None (the absence of a role)</li>
|
||||
</ol><p>
|
||||
|
||||
These roles are temporary in that they do not persist across a user's visits to the room
|
||||
and can change during the course of an occupant's visit to the room.</p><p>
|
||||
|
||||
A moderator is the most powerful occupant within the context of the room, and can to some
|
||||
extent manage other occupants' roles in the room. A participant has fewer privileges than a
|
||||
moderator, although he or she always has the right to speak. A visitor is a more restricted
|
||||
role within the context of a moderated room, since visitors are not allowed to send messages
|
||||
to all occupants.</p><p>
|
||||
|
||||
Roles are granted, revoked, and maintained based on the occupant's room nickname or full
|
||||
JID. Whenever an occupant's role is changed Smack will trigger specific events.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
In order to grant voice (i.e. make someone a <i>participant</i>) just send the message
|
||||
<b>grantVoice(String nickname)</b> to <i><b>MultiUserChat</b></i>. Use <b>revokeVoice(String nickname)</b>
|
||||
to revoke the occupant's voice (i.e. make the occupant a <i>visitor</i>).</p><p>
|
||||
|
||||
In order to grant moderator privileges to a participant or visitor just send the message
|
||||
<b>grantModerator(String nickname)</b> to <i><b>MultiUserChat</b></i>. Use <b>revokeModerator(String nickname)</b>
|
||||
to revoke the moderator privilege from the occupant thus making the occupant a participant.</p><p>
|
||||
|
||||
Smack allows you to listen for role modification events. If you are interested in listening role modification
|
||||
events of any occupant then use the listener <b><i>ParticipantStatusListener</i></b>. But if you are interested
|
||||
in listening for your own role modification events, use the listener <b><i>UserStatusListener</i></b>. Both listeners
|
||||
should be added to the <i><b>MultiUserChat</b></i> by using
|
||||
<b>addParticipantStatusListener(ParticipantStatusListener listener)</b> or
|
||||
<b>addUserStatusListener(UserStatusListener listener)</b> respectively. These listeners include several notification
|
||||
events but you may be interested in just a few of them. Smack provides default implementations for these listeners
|
||||
avoiding you to implement all the interfaces' methods. The default implementations are <b><i>DefaultUserStatusListener</i></b>
|
||||
and <b><i>DefaultParticipantStatusListener</i></b>. Below you will find the sent messages to the listeners whenever
|
||||
an occupant's role has changed.</p><p>
|
||||
|
||||
These are the triggered events when the role has been upgraded:
|
||||
</p>
|
||||
<table border="1">
|
||||
<tr><td><b>Old</b></td><td><b>New</b></td><td><b>Events</b></td></tr>
|
||||
|
||||
<tr><td>None</td><td>Visitor</td><td>--</td></tr>
|
||||
<tr><td>Visitor</td><td>Participant</td><td>voiceGranted</td></tr>
|
||||
<tr><td>Participant</td><td>Moderator</td><td>moderatorGranted</td></tr>
|
||||
|
||||
<tr><td>None</td><td>Participant</td><td>voiceGranted</td></tr>
|
||||
<tr><td>None</td><td>Moderator</td><td>voiceGranted + moderatorGranted</td></tr>
|
||||
<tr><td>Visitor</td><td>Moderator</td><td>voiceGranted + moderatorGranted</td></tr>
|
||||
</table><p>
|
||||
|
||||
These are the triggered events when the role has been downgraded:
|
||||
</p>
|
||||
<table border="1">
|
||||
<tr><td><b>Old</b></td><td><b>New</b></td><td><b>Events</b></td></tr>
|
||||
|
||||
<tr><td>Moderator</td><td>Participant</td><td>moderatorRevoked</td></tr>
|
||||
<tr><td>Participant</td><td>Visitor</td><td>voiceRevoked</td></tr>
|
||||
<tr><td>Visitor</td><td>None</td><td>kicked</td></tr>
|
||||
|
||||
<tr><td>Moderator</td><td>Visitor</td><td>voiceRevoked + moderatorRevoked</td></tr>
|
||||
<tr><td>Moderator</td><td>None</td><td>kicked</td></tr>
|
||||
<tr><td>Participant</td><td>None</td><td>kicked</td></tr>
|
||||
</table></p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to grant voice to a visitor and listen for the notification events: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// User1 creates a room</font>
|
||||
muc = new MultiUserChat(conn1, <font color="#0000FF">"myroom@conference.jabber.org"</font>);
|
||||
muc.create(<font color="#0000FF">"testbot"</font>);
|
||||
|
||||
<font color="#3f7f5f">// User1 (which is the room owner) configures the room as a moderated room</font>
|
||||
Form form = muc.getConfigurationForm();
|
||||
Form answerForm = form.createAnswerForm();
|
||||
answerForm.setAnswer(<font color="#0000FF">"muc#roomconfig_moderatedroom"</font>, <font color="#0000FF">"1"</font>);
|
||||
muc.sendConfigurationForm(answerForm);
|
||||
|
||||
<font color="#3f7f5f">// User2 joins the new room (as a visitor)</font>
|
||||
MultiUserChat muc2 = new MultiUserChat(conn2, <font color="#0000FF">"myroom@conference.jabber.org"</font>);
|
||||
muc2.join(<font color="#0000FF">"testbot2"</font>);
|
||||
<font color="#3f7f5f">// User2 will listen for his own "voice" notification events</font>
|
||||
muc2.addUserStatusListener(new DefaultUserStatusListener() {
|
||||
public void voiceGranted() {
|
||||
super.voiceGranted();
|
||||
...
|
||||
}
|
||||
public void voiceRevoked() {
|
||||
super.voiceRevoked();
|
||||
...
|
||||
}
|
||||
});
|
||||
|
||||
<font color="#3f7f5f">// User3 joins the new room (as a visitor)</font>
|
||||
MultiUserChat muc3 = new MultiUserChat(conn3, <font color="#0000FF">"myroom@conference.jabber.org"</font>);
|
||||
muc3.join(<font color="#0000FF">"testbot3"</font>);
|
||||
<font color="#3f7f5f">// User3 will lister for other occupants "voice" notification events</font>
|
||||
muc3.addParticipantStatusListener(new DefaultParticipantStatusListener() {
|
||||
public void voiceGranted(String participant) {
|
||||
super.voiceGranted(participant);
|
||||
...
|
||||
}
|
||||
|
||||
public void voiceRevoked(String participant) {
|
||||
super.voiceRevoked(participant);
|
||||
...
|
||||
}
|
||||
});
|
||||
|
||||
<font color="#3f7f5f">// The room's owner grants voice to user2</font>
|
||||
muc.grantVoice(<font color="#0000FF">"testbot2"</font>);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="afiliation">Manage affiliation modifications</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
There are five defined affiliations that a user can have in relation to a room:</p>
|
||||
<ol start="" type="">
|
||||
<li>Owner</li>
|
||||
<li>Admin</li>
|
||||
<li>Member</li>
|
||||
<li>Outcast</li>
|
||||
<li>None (the absence of an affiliation)</li>
|
||||
</ol><p>
|
||||
|
||||
These affiliations are semi-permanent in that they persist across a user's visits to the room and
|
||||
are not affected by happenings in the room. Affiliations are granted, revoked, and maintained
|
||||
based on the user's bare JID.</p><p>
|
||||
|
||||
If a user without a defined affiliation enters a room, the user's affiliation is defined as "none";
|
||||
however, this affiliation does not persist across visits.</p><p>
|
||||
|
||||
Owners and admins are by definition immune from certain actions. Specifically, an owner or admin cannot
|
||||
be kicked from a room and cannot be banned from a room. An admin must first lose his or her affiliation
|
||||
(i.e., have an affiliation of "none" or "member") before such actions could be performed
|
||||
on them.</p><p>
|
||||
|
||||
The member affiliation provides a way for a room owner or admin to specify a "whitelist" of users
|
||||
who are allowed to enter a members-only room. When a member enters a members-only room, his or her affiliation
|
||||
does not change, no matter what his or her role is. The member affiliation also provides a way for users to
|
||||
effectively register with an open room and thus be permanently associated with that room in some way (one
|
||||
result may be that the user's nickname is reserved in the room).</p><p>
|
||||
|
||||
An outcast is a user who has been banned from a room and who is not allowed to enter the room. Whenever a
|
||||
user's affiliation is changed Smack will trigger specific events.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
In order to grant membership to a room, administrator privileges or owner priveliges just send
|
||||
<b>grantMembership(String jid)</b>, <b>grantAdmin(String jid)</b> or <b>grantOwnership(String jid)</b>
|
||||
to <i><b>MultiUserChat</b></i> respectively. Use <b>revokeMembership(String jid)</b>, <b>revokeAdmin(String jid)</b>
|
||||
or <b>revokeOwnership(String jid)</b> to revoke the membership to a room, administrator privileges or
|
||||
owner priveliges respectively.</p><p>
|
||||
|
||||
In order to ban a user from the room just send the message <b>banUser(String jid, String reason)</b> to
|
||||
<i><b>MultiUserChat</b></i>.</p><p>
|
||||
|
||||
Smack allows you to listen for affiliation modification events. If you are interested in listening affiliation modification
|
||||
events of any user then use the listener <b><i>ParticipantStatusListener</i></b>. But if you are interested
|
||||
in listening for your own affiliation modification events, use the listener <b><i>UserStatusListener</i></b>. Both listeners
|
||||
should be added to the <i><b>MultiUserChat</b></i> by using
|
||||
<b>addParticipantStatusListener(ParticipantStatusListener listener)</b> or
|
||||
<b>addUserStatusListener(UserStatusListener listener)</b> respectively. These listeners include several notification
|
||||
events but you may be interested in just a few of them. Smack provides default implementations for these listeners
|
||||
avoiding you to implement all the interfaces' methods. The default implementations are <b><i>DefaultUserStatusListener</i></b>
|
||||
and <b><i>DefaultParticipantStatusListener</i></b>. Below you will find the sent messages to the listeners whenever
|
||||
a user's affiliation has changed.</p><p>
|
||||
|
||||
These are the triggered events when the affiliation has been upgraded:
|
||||
</p>
|
||||
<table border="1">
|
||||
<tr><td><b>Old</b></td><td><b>New</b></td><td><b>Events</b></td></tr>
|
||||
|
||||
<tr><td>None</td><td>Member</td><td>membershipGranted</td></tr>
|
||||
<tr><td>Member</td><td>Admin</td><td>membershipRevoked + adminGranted</td></tr>
|
||||
<tr><td>Admin</td><td>Owner</td><td>adminRevoked + ownershipGranted</td></tr>
|
||||
|
||||
<tr><td>None</td><td>Admin</td><td>adminGranted</td></tr>
|
||||
<tr><td>None</td><td>Owner</td><td>ownershipGranted</td></tr>
|
||||
<tr><td>Member</td><td>Owner</td><td>membershipRevoked + ownershipGranted</td></tr>
|
||||
</table><p>
|
||||
|
||||
These are the triggered events when the affiliation has been downgraded:
|
||||
</p>
|
||||
<table border="1">
|
||||
<tr><td><b>Old</b></td><td><b>New</b></td><td><b>Events</b></td></tr>
|
||||
|
||||
<tr><td>Owner</td><td>Admin</td><td>ownershipRevoked + adminGranted</td></tr>
|
||||
<tr><td>Admin</td><td>Member</td><td>adminRevoked + membershipGranted</td></tr>
|
||||
<tr><td>Member</td><td>None</td><td>membershipRevoked</td></tr>
|
||||
|
||||
<tr><td>Owner</td><td>Member</td><td>ownershipRevoked + membershipGranted</td></tr>
|
||||
<tr><td>Owner</td><td>None</td><td>ownershipRevoked</td></tr>
|
||||
<tr><td>Admin</td><td>None</td><td>adminRevoked</td></tr>
|
||||
<tr><td><i>Anyone</i></td><td>Outcast</td><td>banned</td></tr>
|
||||
</table></p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to grant admin privileges to a user and listen for the notification events: <br>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// User1 creates a room</font>
|
||||
muc = new MultiUserChat(conn1, <font color="#0000FF">"myroom@conference.jabber.org"</font>);
|
||||
muc.create(<font color="#0000FF">"testbot"</font>);
|
||||
|
||||
<font color="#3f7f5f">// User1 (which is the room owner) configures the room as a moderated room</font>
|
||||
Form form = muc.getConfigurationForm();
|
||||
Form answerForm = form.createAnswerForm();
|
||||
answerForm.setAnswer(<font color="#0000FF">"muc#roomconfig_moderatedroom"</font>, <font color="#0000FF">"1"</font>);
|
||||
muc.sendConfigurationForm(answerForm);
|
||||
|
||||
<font color="#3f7f5f">// User2 joins the new room (as a visitor)</font>
|
||||
MultiUserChat muc2 = new MultiUserChat(conn2, <font color="#0000FF">"myroom@conference.jabber.org"</font>);
|
||||
muc2.join(<font color="#0000FF">"testbot2"</font>);
|
||||
<font color="#3f7f5f">// User2 will listen for his own admin privileges</font>
|
||||
muc2.addUserStatusListener(new DefaultUserStatusListener() {
|
||||
public void membershipRevoked() {
|
||||
super.membershipRevoked();
|
||||
...
|
||||
}
|
||||
public void adminGranted() {
|
||||
super.adminGranted();
|
||||
...
|
||||
}
|
||||
});
|
||||
|
||||
<font color="#3f7f5f">// User3 joins the new room (as a visitor)</font>
|
||||
MultiUserChat muc3 = new MultiUserChat(conn3, <font color="#0000FF">"myroom@conference.jabber.org"</font>);
|
||||
muc3.join(<font color="#0000FF">"testbot3"</font>);
|
||||
<font color="#3f7f5f">// User3 will lister for other users admin privileges</font>
|
||||
muc3.addParticipantStatusListener(new DefaultParticipantStatusListener() {
|
||||
public void membershipRevoked(String participant) {
|
||||
super.membershipRevoked(participant);
|
||||
...
|
||||
}
|
||||
public void adminGranted(String participant) {
|
||||
super.adminGranted(participant);
|
||||
...
|
||||
}
|
||||
});
|
||||
|
||||
<font color="#3f7f5f">// The room's owner grants admin privileges to user2</font>
|
||||
muc.grantAdmin(<font color="#0000FF">"user2@jabber.org"</font>);
|
||||
</pre>
|
||||
</blockquote>
|
||||
</body>
|
||||
|
||||
</html>
|
620
documentation/extensions/muc.md
Normal file
620
documentation/extensions/muc.md
Normal file
|
@ -0,0 +1,620 @@
|
|||
Multi User Chat
|
||||
===============
|
||||
|
||||
Allows configuration of, participation in, and administration of individual
|
||||
text-based conference rooms.
|
||||
|
||||
* Create a new Room
|
||||
* Join a room
|
||||
* Manage room invitations
|
||||
* Discover MUC support
|
||||
* Discover joined rooms
|
||||
* Discover room information
|
||||
* Start a private chat
|
||||
* Manage changes on room subject
|
||||
* Manage role modifications
|
||||
* Manage affiliation modifications
|
||||
|
||||
**XEP related:** [XEP-45](http://www.xmpp.org/extensions/xep-0045.html)
|
||||
|
||||
Create a new Room
|
||||
-----------------
|
||||
|
||||
**Description**
|
||||
|
||||
Allowed users may create new rooms. There are two types of rooms that you can
|
||||
create. **Instant rooms** which are available for immediate access and are
|
||||
automatically created based on some default configuration and **Reserved
|
||||
rooms** which are manually configured by the room creator before anyone is
|
||||
allowed to enter.
|
||||
|
||||
**Usage**
|
||||
|
||||
In order to create a room you will need to first create an instance of
|
||||
_**MultiUserChat**_. The room name passed to the constructor will be the name
|
||||
of the room to create. The next step is to send **create(String nickname)** to
|
||||
the _**MultiUserChat**_ instance where nickname is the nickname to use when
|
||||
joining the room.
|
||||
|
||||
Depending on the type of room that you want to create you will have to use
|
||||
different configuration forms. In order to create an Instant room just send
|
||||
**sendConfigurationForm(Form form)** where form is an empty form. But if you
|
||||
want to create a Reserved room then you should first get the room's
|
||||
configuration form, complete the form and finally send it back to the server.
|
||||
|
||||
**Examples**
|
||||
|
||||
In this example we can see how to create an instant room:
|
||||
|
||||
```
|
||||
// Create a MultiUserChat using a XMPPConnection for a room
|
||||
MultiUserChat muc = new MultiUserChat(conn1, "myroom@conference.jabber.org");
|
||||
|
||||
// Create the room
|
||||
muc.create("testbot");
|
||||
|
||||
// Send an empty room configuration form which indicates that we want
|
||||
// an instant room
|
||||
muc.sendConfigurationForm(new Form(Form.TYPE_SUBMIT));
|
||||
```
|
||||
|
||||
In this example we can see how to create a reserved room. The form is
|
||||
completed with default values:
|
||||
|
||||
|
||||
// Create a MultiUserChat using a XMPPConnection for a room
|
||||
MultiUserChat muc = new MultiUserChat(conn1, "myroom@conference.jabber.org");
|
||||
|
||||
// Create the room
|
||||
muc.create("testbot");
|
||||
|
||||
// Get the the room's configuration form
|
||||
Form form = muc.getConfigurationForm();
|
||||
// Create a new form to submit based on the original form
|
||||
Form submitForm = form.createAnswerForm();
|
||||
// Add default answers to the form to submit
|
||||
for (Iterator fields = form.getFields(); fields.hasNext();) {
|
||||
FormField field = (FormField) fields.next();
|
||||
if (!FormField.TYPE_HIDDEN.equals(field.getType()) && field.getVariable() != null) {
|
||||
// Sets the default value as the answer
|
||||
submitForm.setDefaultAnswer(field.getVariable());
|
||||
}
|
||||
}
|
||||
// Sets the new owner of the room
|
||||
List owners = new ArrayList();
|
||||
owners.add("johndoe@jabber.org");
|
||||
submitForm.setAnswer("muc#roomconfig_roomowners", owners);
|
||||
// Send the completed form (with default values) to the server to configure the room
|
||||
muc.sendConfigurationForm(submitForm);
|
||||
```
|
||||
|
||||
Join a room
|
||||
-----------
|
||||
|
||||
**Description**
|
||||
|
||||
Your usual first step in order to send messages to a room is to join the room.
|
||||
Multi User Chat allows to specify several parameter while joining a room.
|
||||
Basically you can control the amount of history to receive after joining the
|
||||
room as well as provide your nickname within the room and a password if the
|
||||
room is password protected.
|
||||
|
||||
**Usage**
|
||||
|
||||
In order to join a room you will need to first create an instance of
|
||||
_**MultiUserChat**_. The room name passed to the constructor will be the name
|
||||
of the room to join. The next step is to send **join(...)** to the
|
||||
_**MultiUserChat**_ instance. But first you will have to decide which join
|
||||
message to send. If you want to just join the room without a password and
|
||||
without specifying the amount of history to receive then you could use
|
||||
**join(String nickname)** where nickname if your nickname in the room. In case
|
||||
the room requires a password in order to join you could then use **join(String
|
||||
nickname, String password)**. And finally, the most complete way to join a
|
||||
room is to send **join(String nickname, String password, DiscussionHistory
|
||||
history, long timeout)** where nickname is your nickname in the room, ,
|
||||
password is your password to join the room, history is an object that
|
||||
specifies the amount of history to receive and timeout is the milliseconds to
|
||||
wait for a response from the server.
|
||||
|
||||
**Examples**
|
||||
|
||||
In this example we can see how to join a room with a given nickname:
|
||||
|
||||
```
|
||||
// Create a MultiUserChat using a XMPPConnection for a room
|
||||
MultiUserChat muc2 = new MultiUserChat(conn1, "myroom@conference.jabber.org");
|
||||
// User2 joins the new room
|
||||
// The room service will decide the amount of history to send
|
||||
muc2.join("testbot2");
|
||||
```
|
||||
|
||||
In this example we can see how to join a room with a given nickname and
|
||||
password:
|
||||
|
||||
```
|
||||
// Create a MultiUserChat using a XMPPConnection for a room
|
||||
MultiUserChat muc2 = new MultiUserChat(conn1, "myroom@conference.jabber.org");
|
||||
|
||||
// User2 joins the new room using a password
|
||||
// The room service will decide the amount of history to send
|
||||
muc2.join("testbot2", "password");
|
||||
```
|
||||
|
||||
In this example we can see how to join a room with a given nickname specifying
|
||||
the amount of history to receive:
|
||||
|
||||
```
|
||||
// Create a MultiUserChat using a XMPPConnection for a room
|
||||
MultiUserChat muc2 = new MultiUserChat(conn1, "myroom@conference.jabber.org");
|
||||
|
||||
// User2 joins the new room using a password and specifying
|
||||
// the amount of history to receive. In this example we are requesting the last 5 messages.
|
||||
DiscussionHistory history = new DiscussionHistory();
|
||||
history.setMaxStanzas(5);
|
||||
muc2.join("testbot2", "password", history, conn1.getPacketReplyTimeout());
|
||||
```
|
||||
|
||||
Manage room invitations
|
||||
-----------------------
|
||||
|
||||
**Description**
|
||||
|
||||
It can be useful to invite another user to a room in which one is an occupant.
|
||||
Depending on the room's type the invitee could receive a password to use to
|
||||
join the room and/or be added to the member list if the room is of type
|
||||
members-only. Smack allows to send room invitations and let potential invitees
|
||||
to listening for room invitations and inviters to listen for invitees'
|
||||
rejections.
|
||||
|
||||
**Usage**
|
||||
|
||||
In order to invite another user to a room you must be already joined to the
|
||||
room. Once you are joined just send **invite(String participant, String
|
||||
reason)** to the _**MultiUserChat**_ where participant is the user to invite
|
||||
to the room (e.g. hecate@shakespeare.lit) and reason is the reason why the
|
||||
user is being invited.
|
||||
|
||||
If potential invitees want to listen for room invitations then the invitee
|
||||
must add an _**InvitationListener**_ to the _**MultiUserChat**_ class. Since
|
||||
the _**InvitationListener**_ is an _interface_, it is necessary to create a
|
||||
class that implements this _interface_. If an inviter wants to listen for room
|
||||
invitation rejections, just add an _**InvitationRejectionListener**_ to the
|
||||
_**MultiUserChat**_. _**InvitationRejectionListener**_ is also an interface so
|
||||
you will need to create a class that implements this interface.
|
||||
|
||||
**Examples**
|
||||
|
||||
In this example we can see how to invite another user to the room and lister
|
||||
for possible rejections:
|
||||
|
||||
```
|
||||
// User2 joins the room
|
||||
MultiUserChat muc2 = new MultiUserChat(conn2, room);
|
||||
muc2.join("testbot2");
|
||||
// User2 listens for invitation rejections
|
||||
muc2.addInvitationRejectionListener(new InvitationRejectionListener() {
|
||||
public void invitationDeclined(String invitee, String reason) {
|
||||
// Do whatever you need here...
|
||||
}
|
||||
});
|
||||
// User2 invites user3 to join to the room
|
||||
muc2.invite("user3@host.org/Smack", "Meet me in this excellent room");
|
||||
```
|
||||
|
||||
In this example we can see how to listen for room invitations and decline
|
||||
invitations:
|
||||
|
||||
```
|
||||
// User3 listens for MUC invitations
|
||||
MultiUserChat.addInvitationListener(conn3, new InvitationListener() {
|
||||
public void invitationReceived(XMPPConnection conn, String room, String inviter, String reason, String password) {
|
||||
// Reject the invitation
|
||||
MultiUserChat.decline(conn, room, inviter, "I'm busy right now");
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Discover MUC support
|
||||
--------------------
|
||||
|
||||
**Description**
|
||||
|
||||
A user may want to discover if one of the user's contacts supports the Multi-
|
||||
User Chat protocol.
|
||||
|
||||
**Usage**
|
||||
|
||||
In order to discover if one of the user's contacts supports MUC just send
|
||||
**isServiceEnabled(XMPPConnection connection, String user)** to the
|
||||
_**MultiUserChat**_ class where user is a fully qualified XMPP ID, e.g.
|
||||
jdoe@example.com. You will receive a boolean indicating whether the user
|
||||
supports MUC or not.
|
||||
|
||||
**Examples**
|
||||
|
||||
In this example we can see how to discover support of MUC:
|
||||
|
||||
```
|
||||
// Discover whether user3@host.org supports MUC or not
|
||||
boolean supports = MultiUserChat.isServiceEnabled(conn, "user3@host.org/Smack");
|
||||
```
|
||||
|
||||
Discover joined rooms
|
||||
---------------------
|
||||
|
||||
**Description**
|
||||
|
||||
A user may also want to query a contact regarding which rooms the contact is
|
||||
in.
|
||||
|
||||
**Usage**
|
||||
|
||||
In order to get the rooms where a user is in just send
|
||||
**getJoinedRooms(XMPPConnection connection, String user)** to the
|
||||
_**MultiUserChat**_ class where user is a fully qualified XMPP ID, e.g.
|
||||
jdoe@example.com. You will get an Iterator of Strings as an answer where each
|
||||
String represents a room name.
|
||||
|
||||
**Examples**
|
||||
|
||||
In this example we can see how to get the rooms where a user is in:
|
||||
|
||||
```
|
||||
// Get the rooms where user3@host.org has joined
|
||||
Iterator joinedRooms = MultiUserChat.getJoinedRooms(conn, "user3@host.org/Smack");
|
||||
```
|
||||
|
||||
Discover room information
|
||||
-------------------------
|
||||
|
||||
**Description**
|
||||
|
||||
A user may need to discover information about a room without having to
|
||||
actually join the room. The server will provide information only for public
|
||||
rooms.
|
||||
|
||||
**Usage**
|
||||
|
||||
In order to discover information about a room just send
|
||||
**getRoomInfo(XMPPConnection connection, String room)** to the
|
||||
_**MultiUserChat**_ class where room is the XMPP ID of the room, e.g.
|
||||
roomName@conference.myserver. You will get a RoomInfo object that contains the
|
||||
discovered room information.
|
||||
|
||||
**Examples**
|
||||
|
||||
In this example we can see how to discover information about a room:
|
||||
|
||||
```
|
||||
// Discover information about the room roomName@conference.myserver
|
||||
RoomInfo info = MultiUserChat.getRoomInfo(conn, "roomName@conference.myserver");
|
||||
System.out.println("Number of occupants:" + info.getOccupantsCount());
|
||||
System.out.println("Room Subject:" + info.getSubject());
|
||||
```
|
||||
|
||||
Start a private chat
|
||||
--------------------
|
||||
|
||||
**Description**
|
||||
|
||||
A room occupant may want to start a private chat with another room occupant
|
||||
even though they don't know the fully qualified XMPP ID (e.g.
|
||||
jdoe@example.com) of each other.
|
||||
|
||||
**Usage**
|
||||
|
||||
To create a private chat with another room occupant just send
|
||||
**createPrivateChat(String participant)** to the _**MultiUserChat**_ that you
|
||||
used to join the room. The parameter participant is the occupant unique room
|
||||
JID (e.g. 'darkcave@macbeth.shakespeare.lit/Paul'). You will receive a regular
|
||||
_**Chat**_ object that you can use to chat with the other room occupant.
|
||||
|
||||
**Examples**
|
||||
|
||||
In this example we can see how to start a private chat with another room
|
||||
occupant:
|
||||
|
||||
```
|
||||
// Start a private chat with another participant
|
||||
Chat chat = muc2.createPrivateChat("myroom@conference.jabber.org/johndoe");
|
||||
chat.sendMessage("Hello there");
|
||||
```
|
||||
|
||||
Manage changes on room subject
|
||||
------------------------------
|
||||
|
||||
**Description**
|
||||
|
||||
A common feature of multi-user chat rooms is the ability to change the subject
|
||||
within the room. As a default, only users with a role of "moderator" are
|
||||
allowed to change the subject in a room. Although some rooms may be configured
|
||||
to allow a mere participant or even a visitor to change the subject.
|
||||
|
||||
Every time the room's subject is changed you may want to be notified of the
|
||||
modification. The new subject could be used to display an in-room message.
|
||||
|
||||
**Usage**
|
||||
|
||||
In order to modify the room's subject just send **changeSubject(String
|
||||
subject)** to the _**MultiUserChat**_ that you used to join the room where
|
||||
subject is the new room's subject. On the other hand, if you want to be
|
||||
notified whenever the room's subject is modified you should add a
|
||||
_**SubjectUpdatedListener**_ to the _**MultiUserChat**_ by sending
|
||||
**addSubjectUpdatedListener(SubjectUpdatedListener listener)** to the
|
||||
_**MultiUserChat**_. Since the _**SubjectUpdatedListener**_ is an _interface_,
|
||||
it is necessary to create a class that implements this _interface_.
|
||||
|
||||
**Examples**
|
||||
|
||||
In this example we can see how to change the room's subject and react whenever
|
||||
the room's subject is modified:
|
||||
|
||||
```
|
||||
// An occupant wants to be notified every time the room's subject is changed
|
||||
muc3.addSubjectUpdatedListener(new SubjectUpdatedListener() {
|
||||
public void subjectUpdated(String subject, String from) {
|
||||
....
|
||||
}
|
||||
});
|
||||
// A room's owner changes the room's subject
|
||||
muc2.changeSubject("New Subject");
|
||||
```
|
||||
|
||||
Manage role modifications
|
||||
-------------------------
|
||||
|
||||
**Description**
|
||||
|
||||
There are four defined roles that an occupant can have:
|
||||
|
||||
1. Moderator
|
||||
2. Participant
|
||||
3. Visitor
|
||||
4. None (the absence of a role)
|
||||
|
||||
These roles are temporary in that they do not persist across a user's visits
|
||||
to the room and can change during the course of an occupant's visit to the
|
||||
room.
|
||||
|
||||
A moderator is the most powerful occupant within the context of the room, and
|
||||
can to some extent manage other occupants' roles in the room. A participant
|
||||
has fewer privileges than a moderator, although he or she always has the right
|
||||
to speak. A visitor is a more restricted role within the context of a
|
||||
moderated room, since visitors are not allowed to send messages to all
|
||||
occupants.
|
||||
|
||||
Roles are granted, revoked, and maintained based on the occupant's room
|
||||
nickname or full JID. Whenever an occupant's role is changed Smack will
|
||||
trigger specific events.
|
||||
|
||||
**Usage**
|
||||
|
||||
In order to grant voice (i.e. make someone a _participant_) just send the
|
||||
message **grantVoice(String nickname)** to _**MultiUserChat**_. Use
|
||||
**revokeVoice(String nickname)** to revoke the occupant's voice (i.e. make the
|
||||
occupant a _visitor_).
|
||||
|
||||
In order to grant moderator privileges to a participant or visitor just send
|
||||
the message **grantModerator(String nickname)** to _**MultiUserChat**_. Use
|
||||
**revokeModerator(String nickname)** to revoke the moderator privilege from
|
||||
the occupant thus making the occupant a participant.
|
||||
|
||||
Smack allows you to listen for role modification events. If you are interested
|
||||
in listening role modification events of any occupant then use the listener
|
||||
**_ParticipantStatusListener_**. But if you are interested in listening for
|
||||
your own role modification events, use the listener **_UserStatusListener_**.
|
||||
Both listeners should be added to the _**MultiUserChat**_ by using
|
||||
**addParticipantStatusListener(ParticipantStatusListener listener)** or
|
||||
**addUserStatusListener(UserStatusListener listener)** respectively. These
|
||||
listeners include several notification events but you may be interested in
|
||||
just a few of them. Smack provides default implementations for these listeners
|
||||
avoiding you to implement all the interfaces' methods. The default
|
||||
implementations are **_DefaultUserStatusListener_** and
|
||||
**_DefaultParticipantStatusListener_**. Below you will find the sent messages
|
||||
to the listeners whenever an occupant's role has changed.
|
||||
|
||||
These are the triggered events when the role has been upgraded:
|
||||
|
||||
| Old | New | Events |
|
||||
|-----|-----|--------|
|
||||
| None | Visitor | -- |
|
||||
| Visitor | Participant | voiceGranted |
|
||||
| Participant | Moderator | moderatorGranted |
|
||||
| None | Participant | voiceGranted |
|
||||
| None | Moderator | voiceGranted + moderatorGranted |
|
||||
| Visitor | Moderator | voiceGranted + moderatorGranted |
|
||||
|
||||
These are the triggered events when the role has been downgraded:
|
||||
|
||||
| Old | New | Events |
|
||||
|-----|-----|--------|
|
||||
| Moderator | Participant | moderatorRevoked |
|
||||
| Participant | Visitor | voiceRevoked |
|
||||
| Visitor | None | kicked |
|
||||
| Moderator | Visitor | voiceRevoked + moderatorRevoked |
|
||||
| Moderator | None | kicked |
|
||||
| Participant | None | kicked |
|
||||
|
||||
**Examples**
|
||||
|
||||
In this example we can see how to grant voice to a visitor and listen for the
|
||||
notification events:
|
||||
|
||||
```
|
||||
// User1 creates a room
|
||||
muc = new MultiUserChat(conn1, "myroom@conference.jabber.org");
|
||||
muc.create("testbot");
|
||||
// User1 (which is the room owner) configures the room as a moderated room
|
||||
Form form = muc.getConfigurationForm();
|
||||
Form answerForm = form.createAnswerForm();
|
||||
answerForm.setAnswer("muc#roomconfig_moderatedroom", "1");
|
||||
muc.sendConfigurationForm(answerForm);
|
||||
// User2 joins the new room (as a visitor)
|
||||
MultiUserChat muc2 = new MultiUserChat(conn2, "myroom@conference.jabber.org");
|
||||
muc2.join("testbot2");
|
||||
// User2 will listen for his own "voice" notification events
|
||||
muc2.addUserStatusListener(new DefaultUserStatusListener() {
|
||||
public void voiceGranted() {
|
||||
super.voiceGranted();
|
||||
...
|
||||
}
|
||||
public void voiceRevoked() {
|
||||
super.voiceRevoked();
|
||||
...
|
||||
}
|
||||
});
|
||||
// User3 joins the new room (as a visitor)
|
||||
MultiUserChat muc3 = new MultiUserChat(conn3, "myroom@conference.jabber.org");
|
||||
muc3.join("testbot3");
|
||||
// User3 will lister for other occupants "voice" notification events
|
||||
muc3.addParticipantStatusListener(new DefaultParticipantStatusListener() {
|
||||
public void voiceGranted(String participant) {
|
||||
super.voiceGranted(participant);
|
||||
...
|
||||
}
|
||||
public void voiceRevoked(String participant) {
|
||||
super.voiceRevoked(participant);
|
||||
...
|
||||
}
|
||||
});
|
||||
|
||||
// The room's owner grants voice to user2
|
||||
muc.grantVoice("testbot2");
|
||||
```
|
||||
|
||||
Manage affiliation modifications
|
||||
--------------------------------
|
||||
|
||||
**Description**
|
||||
|
||||
There are five defined affiliations that a user can have in relation to a
|
||||
room:
|
||||
|
||||
1. Owner
|
||||
2. Admin
|
||||
3. Member
|
||||
4. Outcast
|
||||
5. None (the absence of an affiliation)
|
||||
|
||||
These affiliations are semi-permanent in that they persist across a user's
|
||||
visits to the room and are not affected by happenings in the room.
|
||||
Affiliations are granted, revoked, and maintained based on the user's bare
|
||||
JID.
|
||||
|
||||
If a user without a defined affiliation enters a room, the user's affiliation
|
||||
is defined as "none"; however, this affiliation does not persist across
|
||||
visits.
|
||||
|
||||
Owners and admins are by definition immune from certain actions. Specifically,
|
||||
an owner or admin cannot be kicked from a room and cannot be banned from a
|
||||
room. An admin must first lose his or her affiliation (i.e., have an
|
||||
affiliation of "none" or "member") before such actions could be performed on
|
||||
them.
|
||||
|
||||
The member affiliation provides a way for a room owner or admin to specify a
|
||||
"whitelist" of users who are allowed to enter a members-only room. When a
|
||||
member enters a members-only room, his or her affiliation does not change, no
|
||||
matter what his or her role is. The member affiliation also provides a way for
|
||||
users to effectively register with an open room and thus be permanently
|
||||
associated with that room in some way (one result may be that the user's
|
||||
nickname is reserved in the room).
|
||||
|
||||
An outcast is a user who has been banned from a room and who is not allowed to
|
||||
enter the room. Whenever a user's affiliation is changed Smack will trigger
|
||||
specific events.
|
||||
|
||||
**Usage**
|
||||
|
||||
In order to grant membership to a room, administrator privileges or owner
|
||||
priveliges just send **grantMembership(String jid)**, **grantAdmin(String
|
||||
jid)** or **grantOwnership(String jid)** to _**MultiUserChat**_ respectively.
|
||||
Use **revokeMembership(String jid)**, **revokeAdmin(String jid)** or
|
||||
**revokeOwnership(String jid)** to revoke the membership to a room,
|
||||
administrator privileges or owner priveliges respectively.
|
||||
|
||||
In order to ban a user from the room just send the message **banUser(String
|
||||
jid, String reason)** to _**MultiUserChat**_.
|
||||
|
||||
Smack allows you to listen for affiliation modification events. If you are
|
||||
interested in listening affiliation modification events of any user then use
|
||||
the listener **_ParticipantStatusListener_**. But if you are interested in
|
||||
listening for your own affiliation modification events, use the listener
|
||||
**_UserStatusListener_**. Both listeners should be added to the
|
||||
_**MultiUserChat**_ by using
|
||||
**addParticipantStatusListener(ParticipantStatusListener listener)** or
|
||||
**addUserStatusListener(UserStatusListener listener)** respectively. These
|
||||
listeners include several notification events but you may be interested in
|
||||
just a few of them. Smack provides default implementations for these listeners
|
||||
avoiding you to implement all the interfaces' methods. The default
|
||||
implementations are **_DefaultUserStatusListener_** and
|
||||
**_DefaultParticipantStatusListener_**. Below you will find the sent messages
|
||||
to the listeners whenever a user's affiliation has changed.
|
||||
|
||||
These are the triggered events when the affiliation has been upgraded:
|
||||
|
||||
| Old | New | Events |
|
||||
|-----|-----|--------|
|
||||
| None | Member | membershipGranted |
|
||||
| Member | Admin | membershipRevoked + adminGranted |
|
||||
| Admin | Owner | adminRevoked + ownershipGranted |
|
||||
| None | Admin | adminGranted |
|
||||
| None | Owner | ownershipGranted |
|
||||
| Member | Owner | membershipRevoked + ownershipGranted |
|
||||
|
||||
These are the triggered events when the affiliation has been downgraded:
|
||||
|
||||
| Old | New | Events |
|
||||
|-----|-----|--------|
|
||||
| Owner | Admin | ownershipRevoked + adminGranted |
|
||||
| Admin | Member | adminRevoked + membershipGranted |
|
||||
| Member | None | membershipRevoked |
|
||||
| Owner | Member | ownershipRevoked + membershipGranted |
|
||||
| Owner | None | ownershipRevoked |
|
||||
| Admin | None | adminRevoked |
|
||||
| _Anyone_ | Outcast | banned |
|
||||
|
||||
**Examples**
|
||||
|
||||
In this example we can see how to grant admin privileges to a user and listen
|
||||
for the notification events:
|
||||
|
||||
```
|
||||
// User1 creates a room
|
||||
muc = new MultiUserChat(conn1, "myroom@conference.jabber.org");
|
||||
muc.create("testbot");
|
||||
// User1 (which is the room owner) configures the room as a moderated room
|
||||
Form form = muc.getConfigurationForm();
|
||||
Form answerForm = form.createAnswerForm();
|
||||
answerForm.setAnswer("muc#roomconfig_moderatedroom", "1");
|
||||
muc.sendConfigurationForm(answerForm);
|
||||
// User2 joins the new room (as a visitor)
|
||||
MultiUserChat muc2 = new MultiUserChat(conn2, "myroom@conference.jabber.org");
|
||||
muc2.join("testbot2");
|
||||
// User2 will listen for his own admin privileges
|
||||
muc2.addUserStatusListener(new DefaultUserStatusListener() {
|
||||
public void membershipRevoked() {
|
||||
super.membershipRevoked();
|
||||
...
|
||||
}
|
||||
public void adminGranted() {
|
||||
super.adminGranted();
|
||||
...
|
||||
}
|
||||
});
|
||||
// User3 joins the new room (as a visitor)
|
||||
MultiUserChat muc3 = new MultiUserChat(conn3, "myroom@conference.jabber.org");
|
||||
muc3.join("testbot3");
|
||||
// User3 will lister for other users admin privileges
|
||||
muc3.addParticipantStatusListener(new DefaultParticipantStatusListener() {
|
||||
public void membershipRevoked(String participant) {
|
||||
super.membershipRevoked(participant);
|
||||
...
|
||||
}
|
||||
public void adminGranted(String participant) {
|
||||
super.adminGranted(participant);
|
||||
...
|
||||
}
|
||||
});
|
||||
// The room's owner grants admin privileges to user2
|
||||
muc.grantAdmin("user2@jabber.org");
|
||||
```
|
|
@ -1,164 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Smack: Privacy - Jive Software</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="header">
|
||||
Privacy
|
||||
</div>
|
||||
|
||||
<div class="nav">
|
||||
« <a href="index.html">Table of Contents</a>
|
||||
</div>
|
||||
|
||||
<p class="subheader">What is?</p>
|
||||
<p>
|
||||
<tt>Privacy</tt> is a method for users to block communications from particular other users. In XMPP this is done by managing one's privacy lists.<br />
|
||||
Server-side privacy lists enable successful completion of the following use cases:
|
||||
<ul>
|
||||
<li>Retrieving one's privacy lists.
|
||||
<li>Adding, removing, and editing one's privacy lists.
|
||||
<li>Setting, changing, or declining active lists.
|
||||
<li>Setting, changing, or declining the default list (i.e., the list that is active by default).
|
||||
<li>Allowing or blocking messages based on JID, group, or subscription type (or globally).
|
||||
<li>Allowing or blocking inbound presence notifications based on JID, group, or subscription type (or globally).
|
||||
<li>Allowing or blocking outbound presence notifications based on JID, group, or subscription type (or globally).
|
||||
<li>Allowing or blocking IQ stanzas based on JID, group, or subscription type (or globally).
|
||||
<li>Allowing or blocking all communications based on JID, group, or subscription type (or globally).
|
||||
</ul>
|
||||
<p>
|
||||
|
||||
<p class="subheader">How can I use it?</p>
|
||||
|
||||
<p>
|
||||
The API implementation releases three main public classes:
|
||||
<ul>
|
||||
<li><tt>PrivacyListManager</tt>: this is the main API class to retrieve and handle server privacy lists.
|
||||
<li><tt>PrivacyList</tt>: witch represents one privacy list, with a name, a set of privacy items. For example, the list with visible or invisible.
|
||||
<li><tt>PrivacyItem</tt>: block or allow one aspect of privacy. For example, to allow my friend to see my presence.
|
||||
</ul>
|
||||
<ol>
|
||||
<li> Right from the start, a client MAY <b>get his/her privacy list</b> that is stored in the server:<br />
|
||||
<div class="code">
|
||||
<pre>
|
||||
<font color="gray"><i>// Create a privacy manager for the current connection.</i></font>
|
||||
PrivacyListManager privacyManager = PrivacyListManager.getInstanceFor(myConnection);
|
||||
<font color="gray"><i>// Retrieve server privacy lists</i></font>
|
||||
PrivacyList[] lists = privacyManager.getPrivacyLists();
|
||||
</pre>
|
||||
</div>
|
||||
Now the client is able to show every <tt>PrivacyItem</tt> of the server and also for every list if it is active, default or none of them. The client is a listener of privacy changes.<br />
|
||||
<br />
|
||||
<li> In order to <b>add a new list in the server</b>, the client MAY implement something like:
|
||||
<div class="code">
|
||||
<pre>
|
||||
<font color="gray"><i>// Set the name of the list</i></font>
|
||||
String listName = <font color="green">"newList"</font>;
|
||||
|
||||
<font color="gray"><i>// Create the list of <tt>PrivacyItem</tt> that will allow or deny some privacy aspect</i></font>
|
||||
String user = <font color="green">"tybalt@example.com"</font>;
|
||||
String groupName = <font color="green">"enemies"</font>;
|
||||
ArrayList privacyItems = new ArrayList();
|
||||
|
||||
PrivacyItem item = new PrivacyItem(PrivacyItem.Type.jid, user, <font color="navy">true</font>, 1);
|
||||
privacyItems.add(item);
|
||||
|
||||
item = new PrivacyItem(PrivacyItem.Type.subscription, PrivacyItem.SUBSCRIPTION_BOTH, <font color="navy">true</font>, 2);
|
||||
privacyItems.add(item);
|
||||
|
||||
item = new PrivacyItem(PrivacyItem.Type.group, groupName, <font color="navy">false</font>, 3);
|
||||
item.setFilterMessage(<font color="navy">true</font>);
|
||||
privacyItems.add(item);
|
||||
|
||||
<font color="gray"><i>// Get the privacy manager for the current connection.</i></font>
|
||||
PrivacyListManager privacyManager = PrivacyListManager.getInstanceFor(myConnection);
|
||||
<font color="gray"><i>// Create the new list.</i></font>
|
||||
privacyManager.createPrivacyList(listName, privacyItems);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<li> To <b>modify an existent list</b>, the client code MAY be like:
|
||||
<div class="code">
|
||||
<pre>
|
||||
<font color="gray"><i>// Set the name of the list</i></font>
|
||||
String listName = <font color="green">"existingList"</font>;
|
||||
<font color="gray"><i>// Get the privacy manager for the current connection.</i></font>
|
||||
PrivacyListManager privacyManager = PrivacyListManager.getInstanceFor(myConnection);
|
||||
<font color="gray"><i>// Sent the new list to the server.</i></font>
|
||||
privacyManager.updatePrivacyList(listName, items);
|
||||
</pre>
|
||||
</div>
|
||||
Notice <tt>items</tt> was defined at the example 2 and MUST contain all the elements in the list (not the "delta").
|
||||
|
||||
<li> In order to <b>delete an existing list</b>, the client MAY perform something like:
|
||||
<div class="code">
|
||||
<pre>
|
||||
<font color="gray"><i>// Set the name of the list</i></font>
|
||||
String listName = <font color="green">"existingList"</font>;
|
||||
<font color="gray"><i>// Get the privacy manager for the current connection.</i></font>
|
||||
PrivacyListManager privacyManager = PrivacyListManager.getInstanceFor(myConnection);
|
||||
<font color="gray"><i>// Remove the list.</i></font>
|
||||
privacyManager.deletePrivacyList(listName);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<li> In order to <b>decline the use of an active list</b>, the client MAY perform something like:
|
||||
<div class="code">
|
||||
<pre>
|
||||
<font color="gray"><i>// Get the privacy manager for the current connection.</i></font>
|
||||
PrivacyListManager privacyManager = PrivacyListManager.getInstanceFor(myConnection);
|
||||
<font color="gray"><i>// Decline the use of the active list.</i></font>
|
||||
privacyManager.declineActiveList();
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<li> In order to <b>decline the use of a default list</b>, the client MAY perform something like:
|
||||
<div class="code">
|
||||
<pre>
|
||||
<font color="gray"><i>// Get the privacy manager for the current connection.</i></font>
|
||||
PrivacyListManager privacyManager = PrivacyListManager.getInstanceFor(myConnection);
|
||||
<font color="gray"><i>// Decline the use of the default list.</i></font>
|
||||
privacyManager.declineDefaultList();
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
</ol>
|
||||
|
||||
<p class="subheader">Listening for Privacy Changes</p>
|
||||
<p>
|
||||
In order to handle privacy changes, clients SHOULD listen manager's updates.
|
||||
When a list is changed the manager notifies every added listener. Listeners MUST implement the <tt>PrivacyListListener</tt> interface.
|
||||
|
||||
|
||||
|
||||
Clients may need to react when a privacy list is modified. The <tt>PrivacyListManager</tt> lets you add listerners that will be notified when a list has been changed. Listeners should implement the <tt>PrivacyListListener</tt> interface.<br />
|
||||
The most important notification is <tt>updatedPrivacyList</tt> that is performed when a privacy list changes its privacy items.<br />
|
||||
|
||||
The listener becomes notified after performing:
|
||||
<div class="code">
|
||||
<pre>
|
||||
<font color="gray"><i>// Get the privacy manager for the current connection.</i></font>
|
||||
PrivacyListManager privacyManager = PrivacyListManager.getInstanceFor(myConnection);
|
||||
<font color="gray"><i>// Add the listener (this) to get notified</i></font>
|
||||
privacyManager.addListener(<font color="navy">this</font>);
|
||||
</pre>
|
||||
</div>
|
||||
</p>
|
||||
|
||||
<p class="subheader">References</p>
|
||||
<ul>
|
||||
<li><a href="http://xmpp.org/extensions/xep-0016.html">XEP-0016: Privacy Lists</a>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<br clear="all" /><br><br>
|
||||
|
||||
<div class="footer">
|
||||
Copyright © Jive Software 2002-2008
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
139
documentation/extensions/privacy.md
Normal file
139
documentation/extensions/privacy.md
Normal file
|
@ -0,0 +1,139 @@
|
|||
Privacy Lists
|
||||
============
|
||||
|
||||
[XEP-0016: Privacy Lists](http://xmpp.org/extensions/xep-0016.html)
|
||||
|
||||
What is?
|
||||
--------
|
||||
|
||||
`Privacy` is a method for users to block communications from particular other
|
||||
users. In XMPP this is done by managing one's privacy lists.
|
||||
|
||||
Server-side privacy lists enable successful completion of the following use
|
||||
cases:
|
||||
|
||||
* Retrieving one's privacy lists.
|
||||
* Adding, removing, and editing one's privacy lists.
|
||||
* Setting, changing, or declining active lists.
|
||||
* Setting, changing, or declining the default list (i.e., the list that is active by default).
|
||||
* Allowing or blocking messages based on JID, group, or subscription type (or globally).
|
||||
* Allowing or blocking inbound presence notifications based on JID, group, or subscription type (or globally).
|
||||
* Allowing or blocking outbound presence notifications based on JID, group, or subscription type (or globally).
|
||||
* Allowing or blocking IQ stanzas based on JID, group, or subscription type (or globally).
|
||||
* Allowing or blocking all communications based on JID, group, or subscription type (or globally).
|
||||
|
||||
How can I use it?
|
||||
-----------------
|
||||
|
||||
The API implementation releases three main public classes:
|
||||
|
||||
* `PrivacyListManager`: this is the main API class to retrieve and handle server privacy lists.
|
||||
* `PrivacyList`: witch represents one privacy list, with a name, a set of privacy items. For example, the list with visible or invisible.
|
||||
* `PrivacyItem`: block or allow one aspect of privacy. For example, to allow my friend to see my presence.
|
||||
|
||||
1. Right from the start, a client MAY **get his/her privacy list** that is stored in the server:
|
||||
|
||||
```
|
||||
// Create a privacy manager for the current connection._
|
||||
PrivacyListManager privacyManager = PrivacyListManager.getInstanceFor(myConnection);
|
||||
// Retrieve server privacy lists_
|
||||
PrivacyList[] lists = privacyManager.getPrivacyLists();
|
||||
```
|
||||
|
||||
Now the client is able to show every `PrivacyItem` of the server and also for
|
||||
every list if it is active, default or none of them. The client is a listener
|
||||
of privacy changes.
|
||||
|
||||
|
||||
|
||||
2. In order to **add a new list in the server**, the client MAY implement something like:
|
||||
|
||||
```
|
||||
// Set the name of the list_
|
||||
String listName = "newList";
|
||||
|
||||
// Create the list of PrivacyItem that will allow or deny some privacy aspect_
|
||||
String user = "tybalt@example.com";
|
||||
String groupName = "enemies";
|
||||
ArrayList privacyItems = new ArrayList();
|
||||
|
||||
PrivacyItem item = new PrivacyItem(PrivacyItem.Type.jid, user, true, 1);
|
||||
privacyItems.add(item);
|
||||
|
||||
item = new PrivacyItem(PrivacyItem.Type.subscription, PrivacyItem.SUBSCRIPTION_BOTH, true, 2);
|
||||
privacyItems.add(item);
|
||||
|
||||
item = new PrivacyItem(PrivacyItem.Type.group, groupName, false, 3);
|
||||
item.setFilterMessage(true);
|
||||
privacyItems.add(item);
|
||||
|
||||
// Get the privacy manager for the current connection._
|
||||
PrivacyListManager privacyManager = PrivacyListManager.getInstanceFor(myConnection);
|
||||
// Create the new list._
|
||||
privacyManager.createPrivacyList(listName, privacyItems);
|
||||
```
|
||||
|
||||
3. To **modify an existent list**, the client code MAY be like:
|
||||
|
||||
```
|
||||
// Set the name of the list_
|
||||
String listName = "existingList";
|
||||
// Get the privacy manager for the current connection._
|
||||
PrivacyListManager privacyManager = PrivacyListManager.getInstanceFor(myConnection);
|
||||
// Sent the new list to the server._
|
||||
privacyManager.updatePrivacyList(listName, items);
|
||||
```
|
||||
|
||||
Notice `items` was defined at the example 2 and MUST contain all the elements
|
||||
in the list (not the "delta").
|
||||
|
||||
4. In order to **delete an existing list**, the client MAY perform something like:
|
||||
|
||||
```
|
||||
// Set the name of the list_
|
||||
String listName = "existingList";
|
||||
// Get the privacy manager for the current connection._
|
||||
PrivacyListManager privacyManager = PrivacyListManager.getInstanceFor(myConnection);
|
||||
// Remove the list._
|
||||
privacyManager.deletePrivacyList(listName);
|
||||
```
|
||||
|
||||
5. In order to **decline the use of an active list**, the client MAY perform something like:
|
||||
|
||||
```
|
||||
// Get the privacy manager for the current connection._
|
||||
PrivacyListManager privacyManager = PrivacyListManager.getInstanceFor(myConnection);
|
||||
// Decline the use of the active list._
|
||||
privacyManager.declineActiveList();
|
||||
```
|
||||
|
||||
6. In order to **decline the use of a default list**, the client MAY perform something like:
|
||||
|
||||
```
|
||||
// Get the privacy manager for the current connection._
|
||||
PrivacyListManager privacyManager = PrivacyListManager.getInstanceFor(myConnection);
|
||||
// Decline the use of the default list._
|
||||
privacyManager.declineDefaultList();
|
||||
```
|
||||
|
||||
Listening for Privacy Changes
|
||||
|
||||
In order to handle privacy changes, clients SHOULD listen manager's updates.
|
||||
When a list is changed the manager notifies every added listener. Listeners
|
||||
MUST implement the `PrivacyListListener` interface. Clients may need to react
|
||||
when a privacy list is modified. The `PrivacyListManager` lets you add
|
||||
listerners that will be notified when a list has been changed. Listeners
|
||||
should implement the `PrivacyListListener` interface.
|
||||
|
||||
The most important notification is `updatedPrivacyList` that is performed when
|
||||
a privacy list changes its privacy items.
|
||||
|
||||
The listener becomes notified after performing:
|
||||
|
||||
```
|
||||
// Get the privacy manager for the current connection._
|
||||
PrivacyListManager privacyManager = PrivacyListManager.getInstanceFor(myConnection);
|
||||
// Add the listener (this) to get notified_
|
||||
privacyManager.addListener(this);
|
||||
```
|
||||
Copyright (C) Jive Software 2002-2008
|
|
@ -1,30 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Private Data</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="header">Private Data</div><p>
|
||||
|
||||
Manages private data, which is a mechanism to allow users to store arbitrary XML
|
||||
data on an XMPP server. Each private data chunk is defined by a element name and
|
||||
XML namespace. Example private data:
|
||||
|
||||
<pre>
|
||||
<color xmlns="http://example.com/xmpp/color">
|
||||
<favorite>blue</blue>
|
||||
<leastFavorite>puce</leastFavorite>
|
||||
</color>
|
||||
</pre><p>
|
||||
|
||||
<b>XEP related:</b> <a href="http://www.xmpp.org/extensions/xep-0049.html">XEP-49</a>
|
||||
|
||||
<hr>
|
||||
|
||||
<em>More coming soon.</em>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
17
documentation/extensions/privatedata.md
Normal file
17
documentation/extensions/privatedata.md
Normal file
|
@ -0,0 +1,17 @@
|
|||
Private Data
|
||||
============
|
||||
|
||||
Manages private data, which is a mechanism to allow users to store arbitrary
|
||||
XML data on an XMPP server. Each private data chunk is defined by a element
|
||||
name and XML namespace. Example private data:
|
||||
|
||||
```
|
||||
<color xmlns="http://example.com/xmpp/color">
|
||||
<favorite>blue</blue>
|
||||
<leastFavorite>puce</leastFavorite>
|
||||
</color>
|
||||
```
|
||||
|
||||
**XEP related:** [XEP-49](http://www.xmpp.org/extensions/xep-0049.html)
|
||||
|
||||
_More coming soon._
|
|
@ -1,123 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Smack: Packet Properties - Jive Software</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="header">
|
||||
Packet Properties
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Smack provides an easy mechanism for attaching arbitrary properties to packets. Each property
|
||||
has a String name, and a value that is a Java primitive (int, long, float, double, boolean) or
|
||||
any Serializable object (a Java object is Serializable when it implements the Serializable
|
||||
interface).
|
||||
</p>
|
||||
|
||||
<p class="subheader">
|
||||
Using the API
|
||||
</p>
|
||||
|
||||
<p>
|
||||
All major objects have property support, such as Message objects. The following code
|
||||
demonstrates how to set properties:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
Message message = chat.createMessage();
|
||||
JivePropertiesExtension jpe = new JivePropertiesExtension();
|
||||
<font color="gray"><i>// Add a Color object as a property.</i></font>
|
||||
jpe.setProperty(<font color="blue">"favoriteColor"</font>, new Color(0, 0, 255));
|
||||
<font color="gray"><i>// Add an int as a property.</i></font>
|
||||
jpe.setProperty(<font color="blue">"favoriteNumber"</font>, 4);
|
||||
<font color="gray"><i>// Add the JivePropertiesExtension to the message packet</i></font>
|
||||
message.addPacketExtension(jpe);
|
||||
chat.sendMessage(message);
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
Getting those same properties would use the following code:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
Message message = chat.nextMessage();
|
||||
<font color="gray"><i>// Get the JivePropertiesExtension</i></font>
|
||||
JivePropertiesExtension jpe = message.getExtension(JivePropertiesExtension.NAMESPACE);
|
||||
<font color="gray"><i>// Get a Color object property.</i></font>
|
||||
Color favoriteColor = (Color)jpe.getProperty(<font color="blue">"favoriteColor"</font>);
|
||||
<font color="gray"><i>// Get an int property. Note that properties are always returned as
|
||||
// Objects, so we must cast the value to an Integer, then convert
|
||||
// it to an int.</i></font>
|
||||
int favoriteNumber = ((Integer)jpe.getProperty(<font color="blue">"favoriteNumber"</font>)).intValue();
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
For convenience <code>JivePropertiesManager</code> contains two helper
|
||||
methods namely <code>addProperty(Packet packet, String name, Object
|
||||
value)</code> and
|
||||
<code>getProperty(Packet packet, String name)</code>.
|
||||
</p>
|
||||
|
||||
<p class="subheader">
|
||||
Objects as Properties
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Using objects as property values is a very powerful and easy way to exchange data. However,
|
||||
you should keep the following in mind:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>When you send a Java object as a property, only clients running Java will be able to
|
||||
interpret the data. So, consider using a series of primitive values to transfer data
|
||||
instead.
|
||||
|
||||
<li>Objects sent as property values must implement Serialiable. Additionally, both the sender
|
||||
and receiver must have identical versions of the class, or a serialization exception
|
||||
will occur when de-serializing the object.
|
||||
|
||||
<li>Serialized objects can potentially be quite large, which will use more bandwidth and
|
||||
server resources.
|
||||
</ul>
|
||||
|
||||
<p class="subheader">
|
||||
XML Format
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The current XML format used to send property data is not a standard, so will likely not be
|
||||
recognized by clients not using Smack. The XML looks like the following (comments added for
|
||||
clarity):
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
<font color="gray"><i><!-- All properties are in a x block. --></i></font>
|
||||
<properties xmlns="http://www.jivesoftware.com/xmlns/xmpp/properties">
|
||||
<font color="gray"><i><!-- First, a property named "prop1" that's an integer. --></i></font>
|
||||
<property>
|
||||
<name>prop1</name>
|
||||
<value type="integer">123</value>
|
||||
<property>
|
||||
<font color="gray"><i><!-- Next, a Java object that's been serialized and then converted
|
||||
from binary data to base-64 encoded text. --></i></font>
|
||||
<property>
|
||||
<name>blah2</name>
|
||||
<value type="java-object">adf612fna9nab</value>
|
||||
<property>
|
||||
</properties>
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
The currently supported types are: <tt>integer</tt>, <tt>long</tt>, <tt>float</tt>,
|
||||
<tt>double</tt>, <tt>boolean</tt>, <tt>string</tt>, and <tt>java-object</tt>.
|
||||
</p>
|
||||
|
||||
<div class="footer">
|
||||
Copyright © Jive Software 2002-2008
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
83
documentation/extensions/properties.md
Normal file
83
documentation/extensions/properties.md
Normal file
|
@ -0,0 +1,83 @@
|
|||
Packet Properties
|
||||
=================
|
||||
|
||||
Smack provides an easy mechanism for attaching arbitrary properties to
|
||||
packets. Each property has a String name, and a value that is a Java primitive
|
||||
(int, long, float, double, boolean) or any Serializable object (a Java object
|
||||
is Serializable when it implements the Serializable interface).
|
||||
|
||||
Using the API
|
||||
-------------
|
||||
|
||||
All major objects have property support, such as Message objects. The
|
||||
following code demonstrates how to set properties:
|
||||
|
||||
```
|
||||
Message message = chat.createMessage();
|
||||
JivePropertiesExtension jpe = new JivePropertiesExtension();
|
||||
// Add a Color object as a property._
|
||||
jpe.setProperty("favoriteColor", new Color(0, 0, 255));
|
||||
// Add an int as a property._
|
||||
jpe.setProperty("favoriteNumber", 4);
|
||||
// Add the JivePropertiesExtension to the message packet_
|
||||
message.addPacketExtension(jpe);
|
||||
chat.sendMessage(message);
|
||||
```
|
||||
|
||||
Getting those same properties would use the following code:
|
||||
|
||||
```
|
||||
Message message = chat.nextMessage();
|
||||
// Get the JivePropertiesExtension_
|
||||
JivePropertiesExtension jpe = message.getExtension(JivePropertiesExtension.NAMESPACE);
|
||||
// Get a Color object property._
|
||||
Color favoriteColor = (Color)jpe.getProperty("favoriteColor");
|
||||
// Get an int property. Note that properties are always returned as
|
||||
// Objects, so we must cast the value to an Integer, then convert
|
||||
// it to an int._
|
||||
int favoriteNumber = ((Integer)jpe.getProperty("favoriteNumber")).intValue();
|
||||
```
|
||||
|
||||
For convenience `JivePropertiesManager` contains two helper methods namely
|
||||
`addProperty(Packet packet, String name, Object value)` and
|
||||
`getProperty(Packet packet, String name)`.
|
||||
|
||||
Objects as Properties
|
||||
---------------------
|
||||
|
||||
Using objects as property values is a very powerful and easy way to exchange
|
||||
data. However, you should keep the following in mind:
|
||||
|
||||
* When you send a Java object as a property, only clients running Java will be able to interpret the data. So, consider using a series of primitive values to transfer data instead.
|
||||
* Objects sent as property values must implement Serialiable. Additionally, both the sender and receiver must have identical versions of the class, or a serialization exception will occur when de-serializing the object.
|
||||
* Serialized objects can potentially be quite large, which will use more bandwidth and server resources.
|
||||
|
||||
XML Format
|
||||
----------
|
||||
|
||||
The current XML format used to send property data is not a standard, so will
|
||||
likely not be recognized by clients not using Smack. The XML looks like the
|
||||
following (comments added for clarity):
|
||||
|
||||
|
||||
|
||||
<!-- All properties are in a x block. -->
|
||||
<properties xmlns="http://www.jivesoftware.com/xmlns/xmpp/properties">
|
||||
<!-- First, a property named "prop1" that's an integer. -->
|
||||
<property>
|
||||
<name>prop1</name>
|
||||
<value type="integer">123</value>
|
||||
<property>
|
||||
<!-- Next, a Java object that's been serialized and then converted
|
||||
from binary data to base-64 encoded text. -->
|
||||
<property>
|
||||
<name>blah2</name>
|
||||
<value type="java-object">adf612fna9nab</value>
|
||||
<property>
|
||||
</properties>
|
||||
|
||||
|
||||
The currently supported types are: `integer`, `long`, `float`, `double`,
|
||||
`boolean`, `string`, and `java-object`.
|
||||
|
||||
Copyright (C) Jive Software 2002-2008
|
|
@ -1,448 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>PubSub</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="header">Pubsub</div><p>
|
||||
This section details the usage of an API designed for accessing an XMPP based
|
||||
implementation of a <a href="http://en.wikipedia.org/wiki/Publish/subscribe">publish and subscribe</a>
|
||||
based messaging system. It has functionality for creation, configuration of,
|
||||
subscription and publishing to pubsub nodes.<p>
|
||||
|
||||
<ul>
|
||||
<li><a href="#create">Node creation and configuration</a></li>
|
||||
<li><a href="#publish">Publishing to a node</a></li>
|
||||
<li><a href="#subscribe">Receiving pubsub messages</a></li>
|
||||
<li><a href="#retrieve">Retrieving persisted pubsub messages</a></li>
|
||||
<li><a href="#discopubsub">Discover pubsub information</a></li>
|
||||
</ul>
|
||||
<b>XEP related:</b> <a href="http://xmpp.org/extensions/xep-0060.html">XEP-0060</a>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="create">Node creation and configuration</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
Allowed users may create and configure pubsub nodes. There are two types of nodes that can be created,
|
||||
leaf nodes and collection nodes.
|
||||
<li>Leaf Nodes - contains only messages</li>
|
||||
<li>Collection Nodes - contains only nodes (both Leaf and Collection are allowed), but no messages</li>
|
||||
|
||||
The current version of this API only supports Leaf Nodes.
|
||||
|
||||
There are many configuration options available for nodes, but the two main options are whether the node
|
||||
is <b>persistent</b> or not and whether it will deliver payload or not.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
In order to create a node you will need to first create an instance of <i><b>PubSubManager</b></i>. There
|
||||
are several options for node creation which range from creating an instant node, default configuration, or
|
||||
a fully configured node.</p><p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
Create an instant node: <br>
|
||||
<blockquote>
|
||||
<pre>
|
||||
<font color="#3f7f5f">// Create a pubsub manager using an existing XMPPConnection</font>
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
<font color="#3f7f5f">// Create the node</font>
|
||||
LeafNode leaf = mgr.createNode();
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
Create a node with default configuration and then configure it: <br>
|
||||
<blockquote>
|
||||
<pre>
|
||||
<font color="#3f7f5f">// Create a pubsub manager using an existing XMPPConnection</font>
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
<font color="#3f7f5f">// Create the node</font>
|
||||
LeafNode leaf = mgr.createNode(<font color="#0000FF">"testNode"</font>);
|
||||
ConfigureForm form = new ConfigureForm(FormType.submit);
|
||||
form.setAccessModel(AccessModel.open);
|
||||
form.setDeliverPayloads(false);
|
||||
form.setNotifyRetract(true);
|
||||
form.setPersistentItems(true);
|
||||
form.setPublishModel(PublishModel.open);
|
||||
|
||||
leaf.sendConfigurationForm(form);
|
||||
|
||||
</pre>
|
||||
</blockquote>
|
||||
Create and configure a node: <br>
|
||||
<blockquote>
|
||||
<pre>
|
||||
<font color="#3f7f5f">// Create a pubsub manager using an existing XMPPConnection</font>
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
<font color="#3f7f5f">// Create the node</font>
|
||||
ConfigureForm form = new ConfigureForm(FormType.submit);
|
||||
form.setAccessModel(AccessModel.open);
|
||||
form.setDeliverPayloads(false);
|
||||
form.setNotifyRetract(true);
|
||||
form.setPersistentItems(true);
|
||||
form.setPublishModel(PublishModel.open);
|
||||
LeafNode leaf = mgr.createNode(<font color="#0000FF">"testNode"</font>, form);
|
||||
|
||||
</pre>
|
||||
</blockquote>
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="publish">Publishing to a node</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
This section deals with the <b>publish</b> portion of pubsub.
|
||||
|
||||
Usage of a node typically involves either sending or receiving data, referred to as items.
|
||||
Depending on the context of the nodes usage, the item being sent to it can have different
|
||||
properties.
|
||||
|
||||
It can contain application data known as payload, or the publisher may choose to supply
|
||||
meaningful unique id's. Determination of an items acceptable properties is defined by a
|
||||
combination of node configuration and its purpose.
|
||||
</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
To publish to a node, you will have to either create or retrieve an existing node and then
|
||||
create and send items to that node. The ability for any given person to publish to the node
|
||||
will be dependent on its configuration.
|
||||
</p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
In this example we publish an item to a node that does not take payload: <br>
|
||||
<blockquote>
|
||||
<pre>
|
||||
<font color="#3f7f5f">// Create a pubsub manager using an existing XMPPConnection</font>
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
<font color="#3f7f5f">// Get the node</font>
|
||||
LeafNode node = mgr.getNode(<font color="#0000FF">"testNode"</font>);
|
||||
|
||||
<font color="#3f7f5f">// Publish an Item, let service set the id</font>
|
||||
node.send(new Item());
|
||||
|
||||
<font color="#3f7f5f">// Publish an Item with the specified id</font>
|
||||
node.send(new Item(<font color="#0000FF">"123abc"</font>));
|
||||
</pre>
|
||||
</blockquote>
|
||||
In this example we publish an item to a node that does take payload: <br>
|
||||
<blockquote>
|
||||
<pre>
|
||||
<font color="#3f7f5f">// Create a pubsub manager using an existing XMPPConnection</font>
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
<font color="#3f7f5f">// Get the node</font>
|
||||
LeafNode node = mgr.getNode(<font color="#0000FF">"testNode"</font>);
|
||||
|
||||
<font color="#3f7f5f">// Publish an Item with payload</font>
|
||||
node.send(new PayloadItem<SimplePayload>(<font color="#0000FF">"test"</font> + System.currentTimeMillis(),
|
||||
new SimplePayload(<font color="#0000FF">"book"</font>, <font color="#0000FF">"pubsub:test:book"</font>, <font color="#0000FF">"<book xmlns='pubsub:test:book'><title>Two Towers</title></book>"</font>)));
|
||||
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<div class="subheader"><a name="subscribe">Receiving pubsub messages</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
This section deals with the <b>subscribe</b> portion of pubsub.
|
||||
|
||||
As mentioned in the last section, usage of a node typically involves either sending or receiving
|
||||
items. Subscribers are interested in being notified when items are published to the pubsub
|
||||
node. These items may or may not have application specific data (payload), as that
|
||||
is dependent on the context in which the node is being used.
|
||||
</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
To get messages asynchronously when items are published to a node, you will have to
|
||||
<li>Get a node.</li>
|
||||
<li>Create and register a listener.</li>
|
||||
<li>Subscribe to the node.</li>
|
||||
<p>
|
||||
Please note that you should register the listener before subscribing so that all messages
|
||||
sent after subscribing are received. If done in the reverse order, messages that are sent
|
||||
after subscribing but before registering a listener may not be processed as expected.
|
||||
</p></p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to create a listener and register it and then subscribe for
|
||||
messages. <br>
|
||||
<blockquote>
|
||||
<pre>
|
||||
<font color="#3f7f5f">// Create a pubsub manager using an existing XMPPConnection</font>
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
<font color="#3f7f5f">// Get the node</font>
|
||||
LeafNode node = mgr.getNode(<font color="#0000FF">"testNode"</font>);
|
||||
|
||||
node.addItemEventListener(new ItemEventCoordinator<Item>());
|
||||
node.subscribe(myJid);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
Where the listener is defined like so:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
|
||||
class ItemEventCoordinator <T extends Item> implements ItemEventListener<T>
|
||||
{
|
||||
@Override
|
||||
public void handlePublishedItems(ItemPublishEvent<T> items)
|
||||
{
|
||||
System.out.println(<font color="#0000FF">"Item count: "</font> + items.getItems().size());
|
||||
System.out.println(items);
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
In addition to receiving published items, there are notifications for several other
|
||||
events that occur on a node as well.
|
||||
<li>Deleting items or purging all items from a node</li>
|
||||
<li>Changing the node configuration</li>
|
||||
|
||||
<p>
|
||||
In this example we can see how to create a listener, register it and then subscribe for
|
||||
item deletion messages. <br>
|
||||
<blockquote>
|
||||
<pre>
|
||||
<font color="#3f7f5f">// Create a pubsub manager using an existing XMPPConnection</font>
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
<font color="#3f7f5f">// Get the node</font>
|
||||
LeafNode node = mgr.getNode(<font color="#0000FF">"testNode"</font>);
|
||||
|
||||
node.addItemDeleteListener(new ItemDeleteCoordinator<Item>());
|
||||
node.subscribe(myJid);
|
||||
node.deleteItem(<font color="#0000FF">"id_one"</font>);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
Where the handler is defined like so:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
|
||||
class ItemDeleteCoordinator implements ItemDeleteListener<T>
|
||||
{
|
||||
@Override
|
||||
public void handleDeletedItems(ItemDeleteEvent items)
|
||||
{
|
||||
System.out.println(<font color="#0000FF">"Item count: "</font> + items.getItemIds().size());
|
||||
System.out.println(items);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePurge()
|
||||
{
|
||||
System.out.println(<font color="#0000FF">"All items have been deleted from node"</font>);
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
In this example we can see how to create a listener, register it and then subscribe for
|
||||
node configuration messages. <br>
|
||||
<blockquote>
|
||||
<pre>
|
||||
<font color="#3f7f5f">// Create a pubsub manager using an existing XMPPConnection</font>
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
<font color="#3f7f5f">// Get the node</font>
|
||||
Node node = mgr.getNode(<font color="#0000FF">"testNode"</font>);
|
||||
|
||||
node.addConfigurationListener(new NodeConfigCoordinator());
|
||||
node.subscribe(myJid);
|
||||
|
||||
ConfigureForm form = new ConfigureForm(FormType.submit);
|
||||
form.setAccessModel(AccessModel.open);
|
||||
form.setDeliverPayloads(false);
|
||||
form.setNotifyRetract(true);
|
||||
form.setPersistentItems(true);
|
||||
form.setPublishModel(PublishModel.open);
|
||||
|
||||
node.sendConfigurationForm(form);
|
||||
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
Where the handler is defined like so:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
|
||||
class NodeConfigCoordinator implements NodeConfigListener<T>
|
||||
{
|
||||
@Override
|
||||
public void handleNodeConfiguration(ConfigurationEvent config)
|
||||
{
|
||||
System.out.println(<font color="#0000FF">"New configuration"</font>);
|
||||
System.out.println(config.getConfiguration());
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="retrieve">Retrieving persisted pubsub messages</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
When persistent nodes are used, the subscription and registration methods described in the last section
|
||||
will not enable the retrieval of items that already exist in the node. This section deals with the
|
||||
specific methods for retrieving these items.
|
||||
|
||||
There are several means of retrieving existing items. You can retrieve all items at once, the last N
|
||||
items, or the items specified by a collection of id's.
|
||||
|
||||
Please note that the service may, according to the pubsub specification, reply with a list of items
|
||||
that contains only the item id's (no payload) to save on bandwidth. This will not occur when the id's
|
||||
are specified since this is the means of guaranteeing retrieval of payload.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
To synchronously retrieve existing items from a persistent node, you will have to get an instance
|
||||
of a <i><b>LeafNode</b></i> and call one of the retrieve methods.
|
||||
<p>
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to retrieve the existing items from a node: <br>
|
||||
<blockquote>
|
||||
<pre>
|
||||
<font color="#3f7f5f">// Create a pubsub manager using an existing XMPPConnection</font>
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
<font color="#3f7f5f">// Get the node</font>
|
||||
LeafNode node = mgr.getNode(<font color="#0000FF">"testNode"</font>);
|
||||
|
||||
Collection<? extends Item> items = node.getItems();
|
||||
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
In this example we can see how to retrieve the last N existing items: <br>
|
||||
<blockquote>
|
||||
<pre>
|
||||
<font color="#3f7f5f">// Create a pubsub manager using an existing XMPPConnection</font>
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
<font color="#3f7f5f">// Get the node</font>
|
||||
LeafNode node = mgr.getNode(<font color="#0000FF">"testNode"</font>);
|
||||
|
||||
List<? extends Item> items = node.getItems(100);
|
||||
|
||||
</pre>
|
||||
</blockquote>
|
||||
In this example we can see how to retrieve the specified existing items: <br>
|
||||
<blockquote>
|
||||
<pre>
|
||||
|
||||
<font color="#3f7f5f">// Create a pubsub manager using an existing XMPPConnection</font>
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
<font color="#3f7f5f">// Get the node</font>
|
||||
LeafNode node = mgr.getNode(<font color="#0000FF">"testNode"</font>);
|
||||
Collection<String> ids = new ArrayList<String>(3);
|
||||
ids.add("1");
|
||||
ids.add("3");
|
||||
ids.add("4");
|
||||
|
||||
List<? extends Item> items = node.getItems(ids);
|
||||
|
||||
</pre>
|
||||
</blockquote>
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="discopubsub">Discover pubsub information</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
A user may want to query a server or node for a variety of pubsub related information.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
To retrieve information, a user will simply use either the <i><b>PubSubManager</b></i>
|
||||
or <i><b>Node</b></i> classes depending on what type of information is required.
|
||||
|
||||
<b>Examples</b><p>
|
||||
|
||||
In this example we can see how to get pubsub capabilities: <br>
|
||||
<blockquote>
|
||||
<pre>
|
||||
<font color="#3f7f5f">// Create a pubsub manager using an existing XMPPConnection</font>
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
<font color="#3f7f5f">// Get the pubsub features that are supported</font>
|
||||
DiscoverInfo supportedFeatures = mgr.getSupportedFeatures();
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
In this example we can see how to get pubsub subscriptions for all nodes: <br>
|
||||
<blockquote>
|
||||
<pre>
|
||||
<font color="#3f7f5f">// Create a pubsub manager using an existing XMPPConnection</font>
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
<font color="#3f7f5f">// Get all the subscriptions in the pubsub service</font>
|
||||
List<Subscription> subscriptions = mgr.getSubscriptions();
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
In this example we can see how to get all affiliations for the users bare JID on the pubsub service: <br>
|
||||
<blockquote>
|
||||
<pre>
|
||||
<font color="#3f7f5f">// Create a pubsub manager using an existing XMPPConnection</font>
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
<font color="#3f7f5f">// Get the affiliations for the users bare JID</font>
|
||||
List<Affiliation> affiliations = mgr.getAffiliations();
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
In this example we can see how to get information about the node: <br>
|
||||
<blockquote>
|
||||
<pre>
|
||||
<font color="#3f7f5f">// Create a pubsub manager using an existing XMPPConnection</font>
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
Node node = mgr.getNode(<font color="#0000FF">"testNode"</font>);
|
||||
|
||||
<font color="#3f7f5f">// Get the node information</font>
|
||||
DiscoverInfo nodeInfo = node.discoverInfo();
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
In this example we can see how to discover the node items: <br>
|
||||
<blockquote>
|
||||
<pre>
|
||||
<font color="#3f7f5f">// Create a pubsub manager using an existing XMPPConnection</font>
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
Node node = mgr.getNode(<font color="#0000FF">"testNode"</font>);
|
||||
|
||||
<font color="#3f7f5f">// Discover the node items</font>
|
||||
DiscoverItems nodeItems = node.discoverItems();
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
In this example we can see how to get node subscriptions: <br>
|
||||
<blockquote>
|
||||
<pre>
|
||||
<font color="#3f7f5f">// Create a pubsub manager using an existing XMPPConnection</font>
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
Node node = mgr.getNode(<font color="#0000FF">"testNode"</font>);
|
||||
|
||||
<font color="#3f7f5f">// Discover the node subscriptions</font>
|
||||
List<Subscription> subscriptions = node.getSubscriptions();
|
||||
</pre>
|
||||
</blockquote>
|
||||
<hr>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
402
documentation/extensions/pubsub.md
Normal file
402
documentation/extensions/pubsub.md
Normal file
|
@ -0,0 +1,402 @@
|
|||
Pubsub
|
||||
======
|
||||
|
||||
This section details the usage of an API designed for accessing an XMPP based
|
||||
implementation of a [publish and
|
||||
subscribe](http://en.wikipedia.org/wiki/Publish/subscribe) based messaging
|
||||
system. It has functionality for creation, configuration of, subscription and
|
||||
publishing to pubsub nodes.
|
||||
|
||||
* Node creation and configuration
|
||||
* Publishing to a node
|
||||
* Receiving pubsub messages
|
||||
* Retrieving persisted pubsub messages
|
||||
* Discover pubsub information
|
||||
|
||||
**XEP related:** [XEP-0060](http://xmpp.org/extensions/xep-0060.html)
|
||||
|
||||
Node creation and configuration
|
||||
-------------------------------
|
||||
|
||||
### Description
|
||||
|
||||
Allowed users may create and configure pubsub nodes. There are two types of
|
||||
nodes that can be created, leaf nodes and collection nodes.
|
||||
|
||||
* Leaf Nodes - contains only messages
|
||||
* Collection Nodes - contains only nodes (both Leaf and Collection are allowed), but no messages
|
||||
The current version of this API only supports Leaf Nodes. There are many
|
||||
configuration options available for nodes, but the two main options are
|
||||
whether the node is **persistent** or not and whether it will deliver payload
|
||||
or not.
|
||||
|
||||
### Usage
|
||||
|
||||
In order to create a node you will need to first create an instance of
|
||||
_**PubSubManager**_. There are several options for node creation which range
|
||||
from creating an instant node, default configuration, or a fully configured
|
||||
node.
|
||||
|
||||
### Examples
|
||||
|
||||
Create an instant node:
|
||||
|
||||
```
|
||||
// Create a pubsub manager using an existing XMPPConnection
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
// Create the node
|
||||
LeafNode leaf = mgr.createNode();
|
||||
```
|
||||
|
||||
Create a node with default configuration and then configure it:
|
||||
|
||||
```
|
||||
// Create a pubsub manager using an existing XMPPConnection
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
// Create the node
|
||||
LeafNode leaf = mgr.createNode("testNode");
|
||||
ConfigureForm form = new ConfigureForm(FormType.submit);
|
||||
form.setAccessModel(AccessModel.open);
|
||||
form.setDeliverPayloads(false);
|
||||
form.setNotifyRetract(true);
|
||||
form.setPersistentItems(true);
|
||||
form.setPublishModel(PublishModel.open);
|
||||
|
||||
leaf.sendConfigurationForm(form);
|
||||
```
|
||||
|
||||
Create and configure a node:
|
||||
|
||||
```
|
||||
// Create a pubsub manager using an existing XMPPConnection
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
// Create the node
|
||||
ConfigureForm form = new ConfigureForm(FormType.submit);
|
||||
form.setAccessModel(AccessModel.open);
|
||||
form.setDeliverPayloads(false);
|
||||
form.setNotifyRetract(true);
|
||||
form.setPersistentItems(true);
|
||||
form.setPublishModel(PublishModel.open);
|
||||
LeafNode leaf = mgr.createNode("testNode", form);
|
||||
```
|
||||
|
||||
Publishing to a node
|
||||
--------------------
|
||||
|
||||
**Description**
|
||||
|
||||
This section deals with the **publish** portion of pubsub. Usage of a node
|
||||
typically involves either sending or receiving data, referred to as items.
|
||||
Depending on the context of the nodes usage, the item being sent to it can
|
||||
have different properties. It can contain application data known as payload,
|
||||
or the publisher may choose to supply meaningful unique id's. Determination of
|
||||
an items acceptable properties is defined by a combination of node
|
||||
configuration and its purpose.
|
||||
|
||||
**Usage**
|
||||
|
||||
To publish to a node, you will have to either create or retrieve an existing
|
||||
node and then create and send items to that node. The ability for any given
|
||||
person to publish to the node will be dependent on its configuration.
|
||||
|
||||
**Examples**
|
||||
|
||||
In this example we publish an item to a node that does not take payload:
|
||||
|
||||
```
|
||||
// Create a pubsub manager using an existing XMPPConnection
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
// Get the node
|
||||
LeafNode node = mgr.getNode("testNode");
|
||||
|
||||
// Publish an Item, let service set the id
|
||||
node.send(new Item());
|
||||
|
||||
// Publish an Item with the specified id
|
||||
node.send(new Item("123abc"));
|
||||
```
|
||||
|
||||
In this example we publish an item to a node that does take payload:
|
||||
|
||||
```
|
||||
// Create a pubsub manager using an existing XMPPConnection
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
// Get the node
|
||||
LeafNode node = mgr.getNode("testNode");
|
||||
|
||||
// Publish an Item with payload
|
||||
node.send(new PayloadItem("test" + System.currentTimeMillis(),
|
||||
new SimplePayload("book", "pubsub:test:book", "Two Towers")));
|
||||
```
|
||||
|
||||
Receiving pubsub messages
|
||||
-------------------------
|
||||
|
||||
**Description**
|
||||
|
||||
This section deals with the **subscribe** portion of pubsub. As mentioned in
|
||||
the last section, usage of a node typically involves either sending or
|
||||
receiving items. Subscribers are interested in being notified when items are
|
||||
published to the pubsub node. These items may or may not have application
|
||||
specific data (payload), as that is dependent on the context in which the node
|
||||
is being used.
|
||||
|
||||
**Usage**
|
||||
|
||||
To get messages asynchronously when items are published to a node, you will
|
||||
have to
|
||||
|
||||
* Get a node.
|
||||
* Create and register a listener.
|
||||
* Subscribe to the node.
|
||||
|
||||
Please note that you should register the listener before subscribing so that
|
||||
all messages sent after subscribing are received. If done in the reverse
|
||||
order, messages that are sent after subscribing but before registering a
|
||||
listener may not be processed as expected.
|
||||
|
||||
**Examples**
|
||||
|
||||
In this example we can see how to create a listener and register it and then
|
||||
subscribe for messages.
|
||||
|
||||
```
|
||||
// Create a pubsub manager using an existing XMPPConnection
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
// Get the node
|
||||
LeafNode node = mgr.getNode("testNode");
|
||||
|
||||
node.addItemEventListener(new ItemEventCoordinator<Item;>());
|
||||
node.subscribe(myJid);
|
||||
```
|
||||
|
||||
Where the listener is defined like so:
|
||||
|
||||
```
|
||||
class ItemEventCoordinator implements ItemEventListener {
|
||||
@Override
|
||||
public void handlePublishedItems(ItemPublishEvent items) {
|
||||
System.out.println("Item count: " + System.out.println(items);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In addition to receiving published items, there are notifications for several
|
||||
other events that occur on a node as well.
|
||||
|
||||
* Deleting items or purging all items from a node
|
||||
* Changing the node configuration
|
||||
|
||||
In this example we can see how to create a listener, register it and then
|
||||
subscribe for item deletion messages.
|
||||
|
||||
```
|
||||
// Create a pubsub manager using an existing XMPPConnection
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
// Get the node
|
||||
LeafNode node = mgr.getNode("testNode");
|
||||
|
||||
node.addItemDeleteListener(new ItemDeleteCoordinator<Item;>());
|
||||
node.subscribe(myJid);
|
||||
node.deleteItem("id_one");
|
||||
```
|
||||
|
||||
Where the handler is defined like so:
|
||||
|
||||
```
|
||||
class ItemDeleteCoordinator implements ItemDeleteListener {
|
||||
@Override
|
||||
public void handleDeletedItems(ItemDeleteEvent items) {
|
||||
System.out.println("Item count: " + items.getItemIds().size());
|
||||
System.out.println(items);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePurge() {
|
||||
System.out.println("All items have been deleted from node");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In this example we can see how to create a listener, register it and then
|
||||
subscribe for node configuration messages.
|
||||
|
||||
```
|
||||
// Create a pubsub manager using an existing XMPPConnection
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
// Get the node
|
||||
Node node = mgr.getNode("testNode");
|
||||
|
||||
node.addConfigurationListener(new NodeConfigCoordinator());
|
||||
node.subscribe(myJid);
|
||||
|
||||
ConfigureForm form = new ConfigureForm(FormType.submit);
|
||||
form.setAccessModel(AccessModel.open);
|
||||
form.setDeliverPayloads(false);
|
||||
form.setNotifyRetract(true);
|
||||
form.setPersistentItems(true);
|
||||
form.setPublishModel(PublishModel.open);
|
||||
|
||||
node.sendConfigurationForm(form);
|
||||
```
|
||||
|
||||
Where the handler is defined like so:
|
||||
|
||||
```
|
||||
class NodeConfigCoordinator implements NodeConfigListener {
|
||||
@Override
|
||||
public void handleNodeConfiguration(ConfigurationEvent config) {
|
||||
System.out.println("New configuration");
|
||||
System.out.println(config.getConfiguration());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Retrieving persisted pubsub messages
|
||||
------------------------------------
|
||||
|
||||
**Description**
|
||||
|
||||
When persistent nodes are used, the subscription and registration methods
|
||||
described in the last section will not enable the retrieval of items that
|
||||
already exist in the node. This section deals with the specific methods for
|
||||
retrieving these items. There are several means of retrieving existing items.
|
||||
You can retrieve all items at once, the last N items, or the items specified
|
||||
by a collection of id's. Please note that the service may, according to the
|
||||
pubsub specification, reply with a list of items that contains only the item
|
||||
id's (no payload) to save on bandwidth. This will not occur when the id's are
|
||||
specified since this is the means of guaranteeing retrieval of payload.
|
||||
|
||||
**Usage**
|
||||
|
||||
To synchronously retrieve existing items from a persistent node, you will have
|
||||
to get an instance of a _**LeafNode**_ and call one of the retrieve methods.
|
||||
|
||||
**Examples**
|
||||
|
||||
In this example we can see how to retrieve the existing items from a node:
|
||||
|
||||
```
|
||||
// Create a pubsub manager using an existing XMPPConnection
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
// Get the node
|
||||
LeafNode node = mgr.getNode("testNode");
|
||||
|
||||
Collection<? extends Item> items = node.getItems();
|
||||
```
|
||||
|
||||
In this example we can see how to retrieve the last N existing items:
|
||||
|
||||
```
|
||||
// Create a pubsub manager using an existing XMPPConnection
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
// Get the node
|
||||
LeafNode node = mgr.getNode("testNode");
|
||||
|
||||
List<? extends Item> items = node.getItems(100);
|
||||
```
|
||||
|
||||
In this example we can see how to retrieve the specified existing items:
|
||||
|
||||
```
|
||||
// Create a pubsub manager using an existing XMPPConnection
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
// Get the node
|
||||
LeafNode node = mgr.getNode("testNode");
|
||||
Collection<String;> ids = new ArrayList<String;>(3);
|
||||
ids.add("1");
|
||||
ids.add("3");
|
||||
ids.add("4");
|
||||
|
||||
List<? extends Item> items = node.getItems(ids);
|
||||
```
|
||||
|
||||
Discover pubsub information
|
||||
---------------------------
|
||||
|
||||
**Description**
|
||||
|
||||
A user may want to query a server or node for a variety of pubsub related
|
||||
information.
|
||||
|
||||
**Usage**
|
||||
|
||||
To retrieve information, a user will simply use either the _**PubSubManager**_
|
||||
or _**Node**_ classes depending on what type of information is required.
|
||||
|
||||
**Examples**
|
||||
|
||||
In this example we can see how to get pubsub capabilities:
|
||||
|
||||
```
|
||||
// Create a pubsub manager using an existing XMPPConnection
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
// Get the pubsub features that are supported
|
||||
DiscoverInfo supportedFeatures = mgr.getSupportedFeatures();
|
||||
```
|
||||
|
||||
In this example we can see how to get pubsub subscriptions for all nodes:
|
||||
|
||||
```
|
||||
// Create a pubsub manager using an existing XMPPConnection
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
// Get all the subscriptions in the pubsub service
|
||||
List<Subscription;> subscriptions = mgr.getSubscriptions();
|
||||
```
|
||||
|
||||
In this example we can see how to get all affiliations for the users bare JID
|
||||
on the pubsub service:
|
||||
|
||||
```
|
||||
// Create a pubsub manager using an existing XMPPConnection
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
|
||||
// Get the affiliations for the users bare JID
|
||||
List<Affiliation;> affiliations = mgr.getAffiliations();
|
||||
```
|
||||
|
||||
In this example we can see how to get information about the node:
|
||||
|
||||
```
|
||||
// Create a pubsub manager using an existing XMPPConnection
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
Node node = mgr.getNode("testNode");
|
||||
|
||||
// Get the node information
|
||||
DiscoverInfo nodeInfo = node.discoverInfo();
|
||||
```
|
||||
|
||||
In this example we can see how to discover the node items:
|
||||
|
||||
```
|
||||
// Create a pubsub manager using an existing XMPPConnection
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
Node node = mgr.getNode("testNode");
|
||||
|
||||
// Discover the node items
|
||||
DiscoverItems nodeItems = node.discoverItems();
|
||||
```
|
||||
|
||||
In this example we can see how to get node subscriptions:
|
||||
|
||||
```
|
||||
// Create a pubsub manager using an existing XMPPConnection
|
||||
PubSubManager mgr = new PubSubManager(con);
|
||||
Node node = mgr.getNode("testNode");
|
||||
|
||||
// Discover the node subscriptions
|
||||
List<Subscription;> subscriptions = node.getSubscriptions();
|
||||
```
|
|
@ -1,179 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Roster Item Exchange</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="header">Roster Item Exchange</div><p>
|
||||
This extension is used to send rosters, roster groups and roster entries from one XMPP
|
||||
Entity to another. It also provides an easy way to hook up custom logic when entries
|
||||
are received from other XMPP clients.
|
||||
<p>Follow these links to learn how to send and receive roster items:</p>
|
||||
<ul>
|
||||
<li><a href="#riesendroster">Send a complete roster</a></li>
|
||||
<li><a href="#riesendgroup">Send a roster's group</a></li>
|
||||
<li><a href="#riesendentry">Send a roster's entry</a></li>
|
||||
<li><a href="#riercventry">Receive roster entries</a></li>
|
||||
</ul>
|
||||
<b>XEP related:</b> <a href="http://www.xmpp.org/extensions/xep-0093.html">XEP-93</a>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="riesendroster">Send a entire roster</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
Sometimes it is useful to send a whole roster to another user. Smack provides a
|
||||
very easy way to send a complete roster to another XMPP client.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
Create an instance of <i><b>RosterExchangeManager</b></i> and use the <b>#send(Roster, String)</b>
|
||||
message to send a roster to a given user. The first parameter is the roster to send and
|
||||
the second parameter is the id of the user that will receive the roster entries.</p>
|
||||
|
||||
<b>Example</b><p>
|
||||
|
||||
In this example we can see how user1 sends his roster to user2.
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Connect to the server and log in</font>
|
||||
conn1 = new XMPPConnection(host);
|
||||
conn1.login(server_user1, pass1);
|
||||
|
||||
<font color="#3f7f5f">// Create a new roster exchange manager on conn1</font>
|
||||
RosterExchangeManager rosterExchangeManager = new RosterExchangeManager(conn1);
|
||||
<font color="#3f7f5f">// Send user1's roster to user2</font>
|
||||
rosterExchangeManager.send(conn1.getRoster(), user2);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="riesendgroup">Send a roster group</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
It is also possible to send a roster group to another XMPP client. A roster group groups
|
||||
a set of roster entries under a name.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
Create an instance of <i><b>RosterExchangeManager</b></i> and use the <b>#send(RosterGroup, String)</b>
|
||||
message to send a roster group to a given user. The first parameter is the roster group to send and
|
||||
the second parameter is the id of the user that will receive the roster entries.</p>
|
||||
|
||||
<b>Example</b><p>
|
||||
|
||||
In this example we can see how user1 sends his roster groups to user2.
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Connect to the server and log in</font>
|
||||
conn1 = new XMPPConnection(host);
|
||||
conn1.login(server_user1, pass1);
|
||||
|
||||
<font color="#3f7f5f">// Create a new roster exchange manager on conn1</font>
|
||||
RosterExchangeManager rosterExchangeManager = new RosterExchangeManager(conn1);
|
||||
<font color="#3f7f5f">// Send user1's RosterGroups to user2</font>
|
||||
for (Iterator it = conn1.getRoster().getGroups(); it.hasNext(); )
|
||||
rosterExchangeManager.send((RosterGroup)it.next(), user2);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="riesendentry">Send a roster entry</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
Sometimes you may need to send a single roster entry to another XMPP client. Smack also lets you send
|
||||
items at this granularity level.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
Create an instance of <i><b>RosterExchangeManager</b></i> and use the <b>#send(RosterEntry, String)</b>
|
||||
message to send a roster entry to a given user. The first parameter is the roster entry to send and
|
||||
the second parameter is the id of the user that will receive the roster entries.</p>
|
||||
|
||||
<b>Example</b><p>
|
||||
|
||||
In this example we can see how user1 sends a roster entry to user2.
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Connect to the server and log in</font>
|
||||
conn1 = new XMPPConnection(host);
|
||||
conn1.login(server_user1, pass1);
|
||||
|
||||
<font color="#3f7f5f">// Create a new roster exchange manager on conn1</font>
|
||||
RosterExchangeManager rosterExchangeManager = new RosterExchangeManager(conn1);
|
||||
<font color="#3f7f5f">// Send a roster entry (any) to user2</font>
|
||||
rosterExchangeManager1.send((RosterEntry)conn1.getRoster().getEntries().next(), user2);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="riercventry">Receive roster entries</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
Since roster items are sent between XMPP clients, it is necessary to listen to possible roster entries
|
||||
receptions. Smack provides a mechanism that you can use to execute custom logic when roster entries are
|
||||
received.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
<ol>
|
||||
<li>Create a class that implements the <i><b>RosterExchangeListener</b></i> interface.</li>
|
||||
<li>Implement the method <b>entriesReceived(String, Iterator)</b> that will be called when new entries
|
||||
are received with custom logic.</li>
|
||||
<li>Add the listener to the <i>RosterExchangeManager</i> that works on the desired <i>XMPPConnection</i>.</li>
|
||||
</ol></p>
|
||||
|
||||
<b>Example</b><p>
|
||||
|
||||
In this example we can see how user1 sends a roster entry to user2 and user2 adds the received
|
||||
entries to his roster.
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Connect to the server and log in the users</font>
|
||||
conn1 = new XMPPConnection(host);
|
||||
conn1.login(server_user1, pass1);
|
||||
conn2 = new XMPPConnection(host);
|
||||
conn2.login(server_user2, pass2);
|
||||
final Roster user2_roster = conn2.getRoster();
|
||||
|
||||
<font color="#3f7f5f">// Create a RosterExchangeManager that will help user2 to listen and accept
|
||||
the entries received</font>
|
||||
RosterExchangeManager rosterExchangeManager2 = new RosterExchangeManager(conn2);
|
||||
<font color="#3f7f5f">// Create a RosterExchangeListener that will iterate over the received roster entries</font>
|
||||
RosterExchangeListener rosterExchangeListener = new RosterExchangeListener() {
|
||||
public void entriesReceived(String from, Iterator remoteRosterEntries) {
|
||||
while (remoteRosterEntries.hasNext()) {
|
||||
try {
|
||||
<font color="#3f7f5f">// Get the received entry</font>
|
||||
RemoteRosterEntry remoteRosterEntry = (RemoteRosterEntry) remoteRosterEntries.next();
|
||||
<font color="#3f7f5f">// Display the remote entry on the console</font>
|
||||
System.out.println(remoteRosterEntry);
|
||||
<font color="#3f7f5f">// Add the entry to the user2's roster</font>
|
||||
user2_roster.createEntry(
|
||||
remoteRosterEntry.getUser(),
|
||||
remoteRosterEntry.getName(),
|
||||
remoteRosterEntry.getGroupArrayNames());
|
||||
}
|
||||
catch (XMPPException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
<font color="#3f7f5f">// Add the RosterExchangeListener to the RosterExchangeManager that user2 is using</font>
|
||||
rosterExchangeManager2.addRosterListener(rosterExchangeListener);
|
||||
|
||||
<font color="#3f7f5f">// Create a RosterExchangeManager that will help user1 to send his roster</font>
|
||||
RosterExchangeManager rosterExchangeManager1 = new RosterExchangeManager(conn1);
|
||||
<font color="#3f7f5f">// Send user1's roster to user2</font>
|
||||
rosterExchangeManager1.send(conn1.getRoster(), user2);
|
||||
</pre>
|
||||
</blockquote>
|
||||
</body>
|
||||
|
||||
</html>
|
167
documentation/extensions/rosterexchange.md
Normal file
167
documentation/extensions/rosterexchange.md
Normal file
|
@ -0,0 +1,167 @@
|
|||
Roster Item Exchange
|
||||
====================
|
||||
|
||||
This extension is used to send rosters, roster groups and roster entries from
|
||||
one XMPP Entity to another. It also provides an easy way to hook up custom
|
||||
logic when entries are received from other XMPP clients.
|
||||
|
||||
Follow these links to learn how to send and receive roster items:
|
||||
|
||||
* Send a complete roster
|
||||
* Send a roster's group
|
||||
* Send a roster's entry
|
||||
* Receive roster entries
|
||||
|
||||
**XEP related:** [XEP-93](http://www.xmpp.org/extensions/xep-0093.html)
|
||||
|
||||
Send a entire roster
|
||||
-------------------
|
||||
|
||||
**Description**
|
||||
|
||||
Sometimes it is useful to send a whole roster to another user. Smack provides
|
||||
a very easy way to send a complete roster to another XMPP client.
|
||||
|
||||
**Usage**
|
||||
|
||||
Create an instance of _**RosterExchangeManager**_ and use the **#send(Roster,
|
||||
String)** message to send a roster to a given user. The first parameter is the
|
||||
roster to send and the second parameter is the id of the user that will
|
||||
receive the roster entries.
|
||||
|
||||
**Example**
|
||||
|
||||
In this example we can see how user1 sends his roster to user2.
|
||||
|
||||
```
|
||||
// Connect to the server and log in
|
||||
conn1 = new XMPPConnection(host);
|
||||
conn1.login(server_user1, pass1);
|
||||
|
||||
// Create a new roster exchange manager on conn1
|
||||
RosterExchangeManager rosterExchangeManager = new RosterExchangeManager(conn1);
|
||||
// Send user1's roster to user2
|
||||
rosterExchangeManager.send(conn1.getRoster(), user2);
|
||||
```
|
||||
|
||||
Send a roster group
|
||||
-------------------
|
||||
|
||||
**Description**
|
||||
|
||||
It is also possible to send a roster group to another XMPP client. A roster
|
||||
group groups a set of roster entries under a name.
|
||||
|
||||
**Usage**
|
||||
|
||||
Create an instance of _**RosterExchangeManager**_ and use the
|
||||
**#send(RosterGroup, String)** message to send a roster group to a given user.
|
||||
The first parameter is the roster group to send and the second parameter is
|
||||
the id of the user that will receive the roster entries.
|
||||
|
||||
**Example**
|
||||
|
||||
In this example we can see how user1 sends his roster groups to user2.
|
||||
|
||||
```
|
||||
// Connect to the server and log in
|
||||
conn1 = new XMPPConnection(host);
|
||||
conn1.login(server_user1, pass1);
|
||||
|
||||
// Create a new roster exchange manager on conn1
|
||||
RosterExchangeManager rosterExchangeManager = new RosterExchangeManager(conn1);
|
||||
// Send user1's RosterGroups to user2
|
||||
for (Iterator it = conn1.getRoster().getGroups(); it.hasNext(); )
|
||||
rosterExchangeManager.send((RosterGroup)it.next(), user2);
|
||||
```
|
||||
|
||||
Send a roster entry
|
||||
-------------------
|
||||
|
||||
**Description**
|
||||
|
||||
Sometimes you may need to send a single roster entry to another XMPP client.
|
||||
Smack also lets you send items at this granularity level.
|
||||
|
||||
**Usage**
|
||||
|
||||
Create an instance of _**RosterExchangeManager**_ and use the
|
||||
**#send(RosterEntry, String)** message to send a roster entry to a given user.
|
||||
The first parameter is the roster entry to send and the second parameter is
|
||||
the id of the user that will receive the roster entries.
|
||||
|
||||
**Example**
|
||||
|
||||
In this example we can see how user1 sends a roster entry to user2.
|
||||
|
||||
```
|
||||
// Connect to the server and log in
|
||||
conn1 = new XMPPConnection(host);
|
||||
conn1.login(server_user1, pass1);
|
||||
|
||||
// Create a new roster exchange manager on conn1
|
||||
RosterExchangeManager rosterExchangeManager = new RosterExchangeManager(conn1);
|
||||
// Send a roster entry (any) to user2
|
||||
rosterExchangeManager1.send((RosterEntry)conn1.getRoster().getEntries().next(), user2);
|
||||
```
|
||||
|
||||
Receive roster entries
|
||||
----------------------
|
||||
|
||||
**Description**
|
||||
|
||||
Since roster items are sent between XMPP clients, it is necessary to listen to
|
||||
possible roster entries receptions. Smack provides a mechanism that you can
|
||||
use to execute custom logic when roster entries are received.
|
||||
|
||||
**Usage**
|
||||
|
||||
1. Create a class that implements the _**RosterExchangeListener**_ interface.
|
||||
2. Implement the method **entriesReceived(String, Iterator)** that will be called when new entries are received with custom logic.
|
||||
3. Add the listener to the _RosterExchangeManager_ that works on the desired _XMPPConnection_.
|
||||
|
||||
**Example**
|
||||
|
||||
In this example we can see how user1 sends a roster entry to user2 and user2
|
||||
adds the received entries to his roster.
|
||||
|
||||
```
|
||||
// Connect to the server and log in the users
|
||||
conn1 = new XMPPConnection(host);
|
||||
conn1.login(server_user1, pass1);
|
||||
conn2 = new XMPPConnection(host);
|
||||
conn2.login(server_user2, pass2);
|
||||
final Roster user2_roster = conn2.getRoster();
|
||||
|
||||
// Create a RosterExchangeManager that will help user2 to listen and accept
|
||||
the entries received
|
||||
RosterExchangeManager rosterExchangeManager2 = new RosterExchangeManager(conn2);
|
||||
// Create a RosterExchangeListener that will iterate over the received roster entries
|
||||
RosterExchangeListener rosterExchangeListener = new RosterExchangeListener() {
|
||||
public void entriesReceived(String from, Iterator remoteRosterEntries) {
|
||||
while (remoteRosterEntries.hasNext()) {
|
||||
try {
|
||||
// Get the received entry
|
||||
RemoteRosterEntry remoteRosterEntry = (RemoteRosterEntry) remoteRosterEntries.next();
|
||||
// Display the remote entry on the console
|
||||
System.out.println(remoteRosterEntry);
|
||||
// Add the entry to the user2's roster
|
||||
user2_roster.createEntry(
|
||||
remoteRosterEntry.getUser(),
|
||||
remoteRosterEntry.getName(),
|
||||
remoteRosterEntry.getGroupArrayNames());
|
||||
}
|
||||
catch (XMPPException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
// Add the RosterExchangeListener to the RosterExchangeManager that user2 is using
|
||||
rosterExchangeManager2.addRosterListener(rosterExchangeListener);
|
||||
|
||||
// Create a RosterExchangeManager that will help user1 to send his roster
|
||||
RosterExchangeManager rosterExchangeManager1 = new RosterExchangeManager(conn1);
|
||||
// Send user1's roster to user2
|
||||
rosterExchangeManager1.send(conn1.getRoster(), user2);
|
||||
```
|
|
@ -1,57 +0,0 @@
|
|||
BODY {
|
||||
font-size : 100%;
|
||||
background-color : #fff;
|
||||
}
|
||||
BODY, TD, TH {
|
||||
font-family : tahoma, arial, helvetica;
|
||||
font-size : 0.8em;
|
||||
}
|
||||
PRE, TT, CODE {
|
||||
font-family : courier new, monospaced;
|
||||
font-size : 1.0em;
|
||||
}
|
||||
A:hover {
|
||||
text-decoration : none;
|
||||
}
|
||||
LI {
|
||||
padding-bottom : 4px;
|
||||
}
|
||||
.header {
|
||||
font-size : 1.4em;
|
||||
font-weight : bold;
|
||||
width : 100%;
|
||||
border-bottom : 1px #ccc solid;
|
||||
padding-bottom : 2px;
|
||||
}
|
||||
.subheader {
|
||||
font-size: 1.1em;
|
||||
font-weight : bold;
|
||||
}
|
||||
.footer {
|
||||
font-size : 0.8em;
|
||||
color : #999;
|
||||
text-align : center;
|
||||
width : 100%;
|
||||
border-top : 1px #ccc solid;
|
||||
padding-top : 2px;
|
||||
}
|
||||
.code {
|
||||
border : 1px #ccc solid;
|
||||
padding : 0em 1.0em 0em 1.0em;
|
||||
margin : 4px 0px 4px 0px;
|
||||
}
|
||||
.nav, .nav A {
|
||||
font-family : verdana;
|
||||
font-size : 0.85em;
|
||||
color : #600;
|
||||
text-decoration : none;
|
||||
font-weight : bold;
|
||||
}
|
||||
.nav {
|
||||
width : 100%;
|
||||
border-bottom : 1px #ccc solid;
|
||||
padding : 3px 3px 5px 1px;
|
||||
}
|
||||
.nav A:hover {
|
||||
text-decoration : underline;
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Time</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="header">Entity Time Exchange</div><p>
|
||||
|
||||
Supports a protocol that XMPP clients use to exchange their respective local
|
||||
times and time zones.<p>
|
||||
|
||||
<b>XEP related:</b> <a href="http://www.xmpp.org/extensions/xep-0090.html">XEP-90</a>
|
||||
|
||||
<hr>
|
||||
|
||||
<em>More coming soon.</em>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
10
documentation/extensions/time.md
Normal file
10
documentation/extensions/time.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
Entity Time Exchange
|
||||
====================
|
||||
|
||||
Supports a protocol that XMPP clients use to exchange their respective local
|
||||
times and time zones.
|
||||
|
||||
**XEP related:** [XEP-90](http://www.xmpp.org/extensions/xep-0090.html)
|
||||
|
||||
_More coming soon._
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Smack Extensions User Manual</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
<base target="mainFrame">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a href="intro.html">Introduction</a><p>
|
||||
|
||||
<div class="subheader">Smack Extensions</div><p>
|
||||
|
||||
<a href="privatedata.html">Private Data</a><br>
|
||||
<a href="xhtml.html">XHTML Messages</a><br>
|
||||
<a href="messageevents.html">Message Events</a><br>
|
||||
<a href="dataforms.html">Data Forms</a><br>
|
||||
<a href="muc.html">Multi User Chat</a><br>
|
||||
<a href="rosterexchange.html">Roster Item Exchange</a><br>
|
||||
<a href="time.html">Time Exchange</a><br>
|
||||
<a href="invitation.html">Group Chat Invitations</a><br>
|
||||
<a href="disco.html">Service Discovery</a><br>
|
||||
<a href="filetransfer.html">File Transfer</a><br>
|
||||
<a href="pubsub.html">PubSub</a><br>
|
||||
<a href="caps.html">Entity Capabilities</a><br>
|
||||
<a href="privacy.html">Privacy</a><br>
|
||||
<a href="hoxt.html">HTTP over XMPP</a><br>
|
||||
<a href="properties.html">JiveProperties</a>
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,200 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>XHTML Support</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="header">XHTML Messages</div><p>
|
||||
|
||||
Provides the ability to send and receive formatted messages using XHTML.
|
||||
|
||||
<p>Follow these links to learn how to compose, send, receive and discover support for
|
||||
XHTML messages:</p>
|
||||
<ul>
|
||||
<li><a href="#xhtmlcompose">Compose an XHTML Message</a></li>
|
||||
<li><a href="#xhtmlsend">Send an XHTML Message</a></li>
|
||||
<li><a href="#xhtmlreceive">Receive an XHTML Message</a></li>
|
||||
<li><a href="#xhtmldiscover">Discover support for XHTML Messages</a></li>
|
||||
</ul>
|
||||
<b>XEP related:</b> <a href="http://www.xmpp.org/extensions/xep-0071.html">XEP-71</a>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="xhtmlcompose">Compose an XHTML Message</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
The first step in order to send an XHTML message is to compose it. Smack provides a special
|
||||
class that helps to build valid XHTML messages hiding any low level complexity.
|
||||
For special situations, advanced users may decide not to use the helper class and generate
|
||||
the XHTML by themselves. Even for these situations Smack provides a well defined entry point
|
||||
in order to add the generated XHTML content to a given message.</p>
|
||||
|
||||
<p>
|
||||
Note: not all clients are able to view XHTML formatted messages. Therefore,
|
||||
it's recommended that you include a normal body in that message that is either an
|
||||
unformatted version of the text or a note that XHTML support is required
|
||||
to view the message contents.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
Create an instance of <i><b>XHTMLText</b></i> specifying the style and language of the body.
|
||||
You can add several XHTML bodies to the message but each body should be for a different language.
|
||||
Once you have an XHTMLText you can start to append tags and text to it. In order to append tags there
|
||||
are several messages that you can use. For each XHTML defined tag there is a message that you can send.
|
||||
In order to add text you can send the message <b>#append(String textToAppend)</b>.</p>
|
||||
|
||||
<p>After you have configured the XHTML text, the last step you have to do is to add the XHTML text
|
||||
to the message you want to send. If you decided to create the XHTML text by yourself, you will have to
|
||||
follow this last step too. In order to add the XHTML text to the message send the message
|
||||
<b>#addBody(Message message, String body)</b> to the <i><b>XHTMLManager</b></i> class where <i>message</i>
|
||||
is the message that will receive the XHTML body and <i>body</i> is the string to add as an XHTML body to
|
||||
the message.</b></p>
|
||||
|
||||
<b>Example</b><p>
|
||||
|
||||
In this example we can see how to compose the following XHTML message: <br>
|
||||
<font color="#0000FF"><body><p style='font-size:large'>Hey John, this is my new <span
|
||||
style='color:green'>green</span><em>!!!!</em></p></body></font>
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Create a message to send</font>
|
||||
Message msg = chat.createMessage();
|
||||
msg.setSubject(<font color="#0000FF">"Any subject you want"</font>);
|
||||
msg.setBody(<font color="#0000FF">"Hey John, this is my new green!!!!"</font>);
|
||||
|
||||
<font color="#3f7f5f">// Create an XHTMLText to send with the message</font>
|
||||
XHTMLText xhtmlText = new XHTMLText(null, null);
|
||||
xhtmlText.appendOpenParagraphTag(<font color="#0000FF">"font-size:large"</font>);
|
||||
xhtmlText.append(<font color="#0000FF">"Hey John, this is my new "</font>);
|
||||
xhtmlText.appendOpenSpanTag(<font color="#0000FF">"color:green"</font>);
|
||||
xhtmlText.append(<font color="#0000FF">"green"</font>);
|
||||
xhtmlText.appendCloseSpanTag();
|
||||
xhtmlText.appendOpenEmTag();
|
||||
xhtmlText.append(<font color="#0000FF">"!!!!"</font>);
|
||||
xhtmlText.appendCloseEmTag();
|
||||
xhtmlText.appendCloseParagraphTag();
|
||||
|
||||
<font color="#3f7f5f">// Add the XHTML text to the message</font>
|
||||
XHTMLManager.addBody(msg, xhtmlText.toString());
|
||||
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="xhtmlsend">Send an XHTML Message</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
After you have composed an XHTML message you will want to send it. Once you have added
|
||||
the XHTML content to the message you want to send you are almost done. The last step is to send
|
||||
the message as you do with any other message.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
An XHTML message is like any regular message, therefore to send the message you can follow
|
||||
the usual steps you do in order to send a message. For example, to send a message as part
|
||||
of a chat just use the message <b>#send(Message)</b> of <i><b>Chat</b></i> or you can use
|
||||
the message <b>#send(Packet)</b> of <i><b>XMPPConnection</b></i>.</p>
|
||||
|
||||
<b>Example</b><p>
|
||||
|
||||
In this example we can see how to send a message with XHTML content as part of a chat.
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Create a message to send</font>
|
||||
Message msg = chat.createMessage();
|
||||
<font color="#3f7f5f">// Obtain the XHTML text to send from somewhere</font>
|
||||
String xhtmlBody = getXHTMLTextToSend();
|
||||
|
||||
<font color="#3f7f5f">// Add the XHTML text to the message</font>
|
||||
XHTMLManager.addBody(msg, xhtmlBody);
|
||||
|
||||
<font color="#3f7f5f">// Send the message that contains the XHTML</font>
|
||||
chat.sendMessage(msg);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="xhtmlreceive">Receive an XHTML Message</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
It is also possible to obtain the XHTML content from a received message. Remember
|
||||
that the specification defines that a message may contain several XHTML bodies
|
||||
where each body should be for a different language.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
To get the XHTML bodies of a given message just send the message <b>#getBodies(Message)</b>
|
||||
to the class <i><b>XHTMLManager</b></i>. The answer of this message will be an
|
||||
<i><b>Iterator</b></i> with the different XHTML bodies of the message or null if none.</p>
|
||||
|
||||
<b>Example</b><p>
|
||||
|
||||
In this example we can see how to create a PacketListener that obtains the XHTML bodies of any received message.
|
||||
<blockquote>
|
||||
<pre> <font color="#3f7f5f">// Create a listener for the chat and display any XHTML content</font>
|
||||
PacketListener packetListener = new PacketListener() {
|
||||
public void processPacket(Packet packet) {
|
||||
Message message = (Message) packet;
|
||||
<font color="#3f7f5f">// Obtain the XHTML bodies of the message</font>
|
||||
Iterator it = XHTMLManager.getBodies(message);
|
||||
if (it != null) {
|
||||
<font color="#3f7f5f">// Display the bodies on the console</font>
|
||||
while (it.hasNext()) {
|
||||
String body = (String) it.next();
|
||||
System.out.println(body);
|
||||
}
|
||||
}
|
||||
};
|
||||
chat.addMessageListener(packetListener);
|
||||
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="subheader"><a name="xhtmldiscover">Discover support for XHTML Messages</a></div><p>
|
||||
|
||||
<b>Description</b><p>
|
||||
|
||||
Before you start to send XHTML messages to a user you should discover if the user supports XHTML messages.
|
||||
There are two ways to achieve the discovery, explicitly and implicitly. Explicit is when you first try
|
||||
to discover if the user supports XHTML before sending any XHTML message. Implicit is when you send
|
||||
XHTML messages without first discovering if the conversation partner's client supports XHTML and depenging on
|
||||
the answer (normal message or XHTML message) you find out if the user supports XHTML messages or not. This
|
||||
section explains how to explicitly discover for XHTML support.</p>
|
||||
|
||||
<b>Usage</b><p>
|
||||
|
||||
In order to discover if a remote user supports XHTML messages send <b>#isServiceEnabled(XMPPConnection
|
||||
connection, String userID)</b> to the class <i><b>XHTMLManager</b></i> where connection is the connection
|
||||
to use to perform the service discovery and userID is the user to check (A fully qualified xmpp ID,
|
||||
e.g. jdoe@example.com). This message will return true if the specified user handles XHTML messages.</p>
|
||||
|
||||
<b>Example</b><p>
|
||||
|
||||
In this example we can see how to discover if a remote user supports XHTML Messages.
|
||||
<blockquote>
|
||||
<pre> Message msg = chat.createMessage();
|
||||
<font color="#3f7f5f">// Include a normal body in the message</font>
|
||||
msg.setBody(getTextToSend());
|
||||
<font color="#3f7f5f">// Check if the other user supports XHTML messages</font>
|
||||
if (XHTMLManager.isServiceEnabled(connection, chat.getParticipant())) {
|
||||
<font color="#3f7f5f">// Obtain the XHTML text to send from somewhere</font>
|
||||
String xhtmlBody = getXHTMLTextToSend();
|
||||
|
||||
<font color="#3f7f5f">// Include an XHTML body in the message</font>
|
||||
XHTMLManager.addBody(msg, xhtmlBody);
|
||||
}
|
||||
|
||||
<font color="#3f7f5f">// Send the message</font>
|
||||
chat.sendMessage(msg);
|
||||
</pre>
|
||||
</blockquote>
|
||||
</body>
|
||||
|
||||
</html>
|
202
documentation/extensions/xhtml.md
Normal file
202
documentation/extensions/xhtml.md
Normal file
|
@ -0,0 +1,202 @@
|
|||
XHTML Messages
|
||||
==============
|
||||
|
||||
Provides the ability to send and receive formatted messages using XHTML.
|
||||
|
||||
Follow these links to learn how to compose, send, receive and discover support
|
||||
for XHTML messages:
|
||||
|
||||
* Compose an XHTML Message
|
||||
* Send an XHTML Message
|
||||
* Receive an XHTML Message
|
||||
* Discover support for XHTML Messages
|
||||
|
||||
**XEP related:** [XEP-71](http://www.xmpp.org/extensions/xep-0071.html)
|
||||
|
||||
Compose an XHTML Message
|
||||
------------------------
|
||||
|
||||
**Description**
|
||||
|
||||
The first step in order to send an XHTML message is to compose it. Smack
|
||||
provides a special class that helps to build valid XHTML messages hiding any
|
||||
low level complexity. For special situations, advanced users may decide not to
|
||||
use the helper class and generate the XHTML by themselves. Even for these
|
||||
situations Smack provides a well defined entry point in order to add the
|
||||
generated XHTML content to a given message.
|
||||
|
||||
Note: not all clients are able to view XHTML formatted messages. Therefore,
|
||||
it's recommended that you include a normal body in that message that is either
|
||||
an unformatted version of the text or a note that XHTML support is required to
|
||||
view the message contents.
|
||||
|
||||
**Usage**
|
||||
|
||||
Create an instance of _**XHTMLText**_ specifying the style and language of the
|
||||
body. You can add several XHTML bodies to the message but each body should be
|
||||
for a different language. Once you have an XHTMLText you can start to append
|
||||
tags and text to it. In order to append tags there are several messages that
|
||||
you can use. For each XHTML defined tag there is a message that you can send.
|
||||
In order to add text you can send the message **#append(String
|
||||
textToAppend)**.
|
||||
|
||||
After you have configured the XHTML text, the last step you have to do is to
|
||||
add the XHTML text to the message you want to send. If you decided to create
|
||||
the XHTML text by yourself, you will have to follow this last step too. In
|
||||
order to add the XHTML text to the message send the message **#addBody(Message
|
||||
message, String body)** to the _**XHTMLManager**_ class where _message_ is the
|
||||
message that will receive the XHTML body and _body_ is the string to add as an
|
||||
XHTML body to the message.**
|
||||
|
||||
**Example**
|
||||
|
||||
In this example we can see how to compose the following XHTML message:
|
||||
|
||||
```
|
||||
<body>
|
||||
<p style='font-size:large'>Hey John, this is my new
|
||||
<span style='color:green'>green</span>
|
||||
<em>!!!!</em>
|
||||
</p>
|
||||
</body>
|
||||
```
|
||||
|
||||
```
|
||||
// Create a message to send
|
||||
Message msg = chat.createMessage();
|
||||
msg.setSubject("Any subject you want");
|
||||
msg.setBody("Hey John, this is my new green!!!!");
|
||||
|
||||
// Create an XHTMLText to send with the message
|
||||
XHTMLText xhtmlText = new XHTMLText(null, null);
|
||||
xhtmlText.appendOpenParagraphTag("font-size:large");
|
||||
xhtmlText.append("Hey John, this is my new ");
|
||||
xhtmlText.appendOpenSpanTag("color:green");
|
||||
xhtmlText.append("green");
|
||||
xhtmlText.appendCloseSpanTag();
|
||||
xhtmlText.appendOpenEmTag();
|
||||
xhtmlText.append("!!!!");
|
||||
xhtmlText.appendCloseEmTag();
|
||||
xhtmlText.appendCloseParagraphTag();
|
||||
|
||||
// Add the XHTML text to the message
|
||||
XHTMLManager.addBody(msg, xhtmlText.toString());
|
||||
```
|
||||
|
||||
Send an XHTML Message
|
||||
---------------------
|
||||
|
||||
**Description**
|
||||
|
||||
After you have composed an XHTML message you will want to send it. Once you
|
||||
have added the XHTML content to the message you want to send you are almost
|
||||
done. The last step is to send the message as you do with any other message.
|
||||
|
||||
**Usage**
|
||||
|
||||
An XHTML message is like any regular message, therefore to send the message
|
||||
you can follow the usual steps you do in order to send a message. For example,
|
||||
to send a message as part of a chat just use the message **#send(Message)** of
|
||||
_**Chat**_ or you can use the message **#send(Packet)** of
|
||||
_**XMPPConnection**_.
|
||||
|
||||
**Example**
|
||||
|
||||
In this example we can see how to send a message with XHTML content as part of
|
||||
a chat.
|
||||
|
||||
```
|
||||
// Create a message to send
|
||||
Message msg = chat.createMessage();
|
||||
// Obtain the XHTML text to send from somewhere
|
||||
String xhtmlBody = getXHTMLTextToSend();
|
||||
|
||||
// Add the XHTML text to the message
|
||||
XHTMLManager.addBody(msg, xhtmlBody);
|
||||
|
||||
// Send the message that contains the XHTML
|
||||
chat.sendMessage(msg);
|
||||
```
|
||||
|
||||
Receive an XHTML Message
|
||||
------------------------
|
||||
|
||||
**Description**
|
||||
|
||||
It is also possible to obtain the XHTML content from a received message.
|
||||
Remember that the specification defines that a message may contain several
|
||||
XHTML bodies where each body should be for a different language.
|
||||
|
||||
**Usage**
|
||||
|
||||
To get the XHTML bodies of a given message just send the message
|
||||
**#getBodies(Message)** to the class _**XHTMLManager**_. The answer of this
|
||||
message will be an _**Iterator**_ with the different XHTML bodies of the
|
||||
message or null if none.
|
||||
|
||||
**Example**
|
||||
|
||||
In this example we can see how to create a PacketListener that obtains the
|
||||
XHTML bodies of any received message.
|
||||
|
||||
```
|
||||
// Create a listener for the chat and display any XHTML content
|
||||
PacketListener packetListener = new PacketListener() {
|
||||
public void processPacket(Packet packet) {
|
||||
Message message = (Message) packet;
|
||||
// Obtain the XHTML bodies of the message
|
||||
Iterator it = XHTMLManager.getBodies(message);
|
||||
if (it != null) {
|
||||
// Display the bodies on the console
|
||||
while (it.hasNext()) {
|
||||
String body = (String) it.next();
|
||||
System.out.println(body);
|
||||
}
|
||||
}
|
||||
};
|
||||
chat.addMessageListener(packetListener);
|
||||
```
|
||||
|
||||
Discover support for XHTML Messages
|
||||
-----------------------------------
|
||||
|
||||
**Description**
|
||||
|
||||
Before you start to send XHTML messages to a user you should discover if the
|
||||
user supports XHTML messages. There are two ways to achieve the discovery,
|
||||
explicitly and implicitly. Explicit is when you first try to discover if the
|
||||
user supports XHTML before sending any XHTML message. Implicit is when you
|
||||
send XHTML messages without first discovering if the conversation partner's
|
||||
client supports XHTML and depenging on the answer (normal message or XHTML
|
||||
message) you find out if the user supports XHTML messages or not. This section
|
||||
explains how to explicitly discover for XHTML support.
|
||||
|
||||
**Usage**
|
||||
|
||||
In order to discover if a remote user supports XHTML messages send
|
||||
**#isServiceEnabled(XMPPConnection connection, String userID)** to the class
|
||||
_**XHTMLManager**_ where connection is the connection to use to perform the
|
||||
service discovery and userID is the user to check (A fully qualified xmpp ID,
|
||||
e.g. jdoe@example.com). This message will return true if the specified user
|
||||
handles XHTML messages.
|
||||
|
||||
**Example**
|
||||
|
||||
In this example we can see how to discover if a remote user supports XHTML
|
||||
Messages.
|
||||
|
||||
```
|
||||
Message msg = chat.createMessage();
|
||||
// Include a normal body in the message
|
||||
msg.setBody(getTextToSend());
|
||||
// Check if the other user supports XHTML messages
|
||||
if (XHTMLManager.isServiceEnabled(connection, chat.getParticipant())) {
|
||||
// Obtain the XHTML text to send from somewhere
|
||||
String xhtmlBody = getXHTMLTextToSend();
|
||||
// Include an XHTML body in the message
|
||||
qHTMLManager.addBody(msg, xhtmlBody);
|
||||
}
|
||||
|
||||
// Send the message
|
||||
chat.sendMessage(msg);
|
||||
```
|
Loading…
Add table
Add a link
Reference in a new issue