[[dynamicRosters]]
= Dynamic Rosters
:author: not known
:version: v2.0, August 2017: Reformatted for v8.0.0.


== Problem Description
Normal roster contacts stored and created as *dynamic roster parts* are delivered to the end user transparently. The XMPP client doesn't really know what contacts come from its own *static* roster created manually by the user and what contacts come from a *dynamic* roster part; contacts and groups generated dynamically by the server logic.

Some specialized clients need to store extra bits of information about roster contacts. For the normal user *static* roster information can be stored as private data and is available only to this single user. In some cases however, clients need to store information about contacts from the dynamic roster part and this information must be available to all users accessing *dynamic* roster part.

The protocol defined here allows the exchange of information, saving and retrieving extra data about the contacts.

== Syntax and Semantics
Extra contact data is accessed using IQ stanzas, specifically by means of a child element qualified by the *jabber:iq:roster-dynamic* namespace. The child element MAY contain one or more children, each describing a unique contact item. Content of the element is not specified and is implementation dependent. From Tigase's point of view it can contain any valid XML data. Whole element is passed to the DynamicRoster implementation class as is and without any verification. Upon retrieving the contact extra data the DynamicRoster implementation is supposed to provide a valid XML element with all the required data for requested *jid*.

The *jid* attribute specifies the Jabber Identifier (JID) that uniquely identifies the roster item. Inclusion of the *jid* attribute is *REQUIRED*.

Following actions on the extra contact data are allowed:

- *set* - stores extra information about the contact
- *get* - retrieves extra information about the contact

== Retrieving Contact Data
Upon connecting to the server and becoming an active resource, a client can request the extra contact data. This request can be made either before or after requesting the user roster. The client's request for the extra contact data is *OPTIONAL*.

Example: Client requests contact extra data from the server using *get* request:

[source,xml]
-----
<iq type='get' id='rce_1'>
<query xmlns='jabber:iq:roster-dynamic'>
<item jid='archimedes@eureka.com'/>
</query>
</iq>
-----

Example: Client receives contact extra data from the server, but there was either no extra information for the user, or the user was not found in the dynamic roster:

[source,xml]
-----
<iq type='result' id='rce_1'>
<query xmlns='jabber:iq:roster-dynamic'>
<item jid='archimedes@eureka.com'/>
</query>
</iq>
-----

Example: Client receives contact extra data from the server, and there was some extra information found about the contact:

[source,xml]
-----
<iq type='result' id='rce_1'>
<query xmlns='jabber:iq:roster-dynamic'>
<item jid='archimedes@eureka.com'>
<phone>+12 3234 322342</phone>
<note>This is short note about the contact</note>
<fax>+98 2343 3453453</fax>
</item>
</query>
</iq>
-----

== Updating/Saving Extra Information About the Contact
At any time, a client *MAY* update extra contact information on the server.

Example: Client sends contact extra information using *set* request.

[source,xml]
-----
<iq type='set' id='a78b4q6ha463'>
<query xmlns='jabber:iq:roster-dynamic'>
<item jid='archimedes@eureka.com'>
<phone>+22 3344 556677</phone>
<note>he is a smart guy, he knows whether the crown is made from pure gold or not.</note>
</item>
</query>
</iq>
-----

Client responds to the server:

[source,xml]
-----
<iq type='result' id='a78b4q6ha463'/>
-----

A client *MAY* update contact extra information for more than a single item in one request:

Example: Client sends contact extra information using *set* request with many +<item/>+ elements.

[source,xml]
-----
<iq type='set' id='a78b4q6ha464'>
<query xmlns='jabber:iq:roster-dynamic'>
<item jid='archimedes@eureka.com'>
<phone>+22 3344 556677</phone>
<note>he is a smart guy, he knows whether the crown is made from pure gold or not.</note>
</item>
<item jid='newton@eureka.com'>
<phone>+22 3344 556688</phone>
<note>He knows how heavy I am.</note>
</item>
<item jid='pascal@eureka.com'>
<phone>+22 3344 556699</phone>
<note>This guy helped me cure my sickness!</note>
</item>
</query>
</iq>
-----

Client responds to the server:

[source,xml]
-----
<iq type='result' id='a78b4q6ha464'/>
-----

== Configuration
DynamicRoster implementation class should be configured in the *config.tdsl* file. As it's an extension to the *PresenceState*, *PresenceSubscription* and *Roster* plugins classes should be configured either for each plugin:
[source,dsl]
-----
'sess-man' () {
    'jabber:iq:roster' () {
        'dynamic-roster-classes' = 'class1.tigase.com,class2.tigase.com'
    }
    'presence-state' () {
        'dynamic-roster-classes' = 'classList.rosterImplementation.tigase'
    }
    'presence-subscription' () {
        'dynamic-roster-classes' = 'class2.custom.roster,another.class.dynamicRoster'
    }
}
-----
or globally:

[source,dsl]
-----
'sess-man' () {
    'dynamic-rosters' () {
        class (class: custom.dynamicRoster.class) {}
    }
}
-----

*<classes list>* is a comma separated list of classes.
