1
0
mirror of https://github.com/moparisthebest/xeps synced 2024-11-28 12:12:22 -05:00
git-svn-id: file:///home/ksmith/gitmigration/svn/xmpp/trunk@2099 4b5297f7-1745-476d-ba37-a9c6900126ab
This commit is contained in:
Peter Saint-Andre 2008-07-22 20:35:20 +00:00
parent 92e0cb29dd
commit 3f9d4b484c

View File

@ -49,18 +49,15 @@
&ralphm; &ralphm;
<revision> <revision>
<version>1.12pre3</version> <version>1.12pre4</version>
<date>in progress, last updated 2008-07-02</date> <date>in progress, last updated 2008-07-16</date>
<initials>psa</initials> <initials>psa</initials>
<remark> <remark>
<ul> <ul>
<li>Specified that service should return ItemID on successful publish if no ItemID was provided in request.</li> <li>Specified that service should return ItemID on successful publish if no ItemID was provided in request.</li>
<li>Described the use of Result Set Management to return some but not all published items.</li> <li>Described the use of Result Set Management to return some but not all published items.</li>
<li>More clearly defined terminology related to deployment scenarios for collection nodes, with some borrowings from graph theory.</li>
<li>Corrected syntax for associating with and disassociating from a collection node so that it is possible to perform these tasks in relation to the root collection node.</li>
<li>Added note about ignoring delivery options set for configuration of a collection node and instead applying delivery options as configured for the publishing leaf node.</li>
<li>Defined handling of collection node deletion for various deployment scenarios.</li>
<li>Defined pubsub#notify_sub config option so that owners can receive notifications of new subscriptions, unsubscribes, and other subscription changes.</li> <li>Defined pubsub#notify_sub config option so that owners can receive notifications of new subscriptions, unsubscribes, and other subscription changes.</li>
<li>Moved text about collections to new specification.</li>
</ul> </ul>
</remark> </remark>
</revision> </revision>
@ -411,7 +408,7 @@ And by opposing end them?
<table caption='Publish-Subscribe Terms'> <table caption='Publish-Subscribe Terms'>
<tr><td>Authorize Access Model</td><td>A node access model under which an entity can subscribe only through having a subscription request approved by a node owner (subscription requests are accepted but only provisionally) and only subscribers may retrieve items.</td></tr> <tr><td>Authorize Access Model</td><td>A node access model under which an entity can subscribe only through having a subscription request approved by a node owner (subscription requests are accepted but only provisionally) and only subscribers may retrieve items.</td></tr>
<tr><td>Address</td><td>(1) A JID as defined in &xmppcore;, or (2) the combination of a JID and a &xep0030; node.</td></tr> <tr><td>Address</td><td>(1) A JID as defined in &xmppcore;, or (2) the combination of a JID and a &xep0030; node.</td></tr>
<tr><td>Collection Node</td><td>A type of node that contains nodes and/or other collections but no published items. Collections make it possible to represent hierarchial node structures.</td></tr> <tr><td>Collection Node</td><td>A type of node that contains nodes and/or other collections but no published items. Collections make it possible to represent more sophisticated relationships among nodes. Collection nodes are defined in &xep0248;.</td></tr>
<tr><td>Entity</td><td>A JID-addressable Jabber entity (client, service, application, etc.).</td></tr> <tr><td>Entity</td><td>A JID-addressable Jabber entity (client, service, application, etc.).</td></tr>
<tr><td>Event</td><td>A change in the state of a node.</td></tr> <tr><td>Event</td><td>A change in the state of a node.</td></tr>
<tr><td>Instant Node</td><td>A node whose NodeID is automatically generated by a pubsub service.</td></tr> <tr><td>Instant Node</td><td>A node whose NodeID is automatically generated by a pubsub service.</td></tr>
@ -456,7 +453,7 @@ And by opposing end them?
<li>A node MAY be configured to deliver the published payload inside the event notification.</li> <li>A node MAY be configured to deliver the published payload inside the event notification.</li>
<li>A node MAY be configured to persist published items to some persistent storage mechanism.</li> <li>A node MAY be configured to persist published items to some persistent storage mechanism.</li>
<li>A node MAY be configured to persist only a limited number of items.</li> <li>A node MAY be configured to persist only a limited number of items.</li>
<li>A service MAY support collections.</li> <li>A service MAY support collections as described in <cite>XEP-0248</cite>.</li>
<li>A service or node MAY support extended service discovery information (meta-data).</li> <li>A service or node MAY support extended service discovery information (meta-data).</li>
</ul> </ul>
@ -645,7 +642,7 @@ And by opposing end them?
</tr> </tr>
<tr> <tr>
<td>Collection</td> <td>Collection</td>
<td>A node that contains nodes and/or other collections but no published items. Collections make it possible to represent hierarchial node structures.</td> <td>A node that contains nodes and/or other collections but no published items. Collections make it possible to represent more sophisticated relationships among nodes. For details, refer to <cite>XEP-0248</cite>.</td>
</tr> </tr>
</table> </table>
</section2> </section2>
@ -1685,7 +1682,7 @@ And by opposing end them?
</ol> </ol>
<p>These error cases are described more fully in the following sections.</p> <p>These error cases are described more fully in the following sections.</p>
<section4 topic='Insufficient Privileges' anchor='subscriber-configure-error-forbidden'> <section4 topic='Insufficient Privileges' anchor='subscriber-configure-error-forbidden'>
<p>When requesting subscription options, the subscriber MUST specify the JID that is subscribed to the node and SHOULD specify a node (if no node is specified, the service MUST assume that the requesting entity wishes to request subscription options for its subscription to the root collection node; see the <link url='#collections-root'>Root Collection Node</link> section of this document for details).</p> <p>When requesting subscription options, the subscriber MUST specify the JID that is subscribed to the node and SHOULD specify a node (if no node is specified, the service MUST assume that the requesting entity wishes to request subscription options for its subscription to the root collection node; refer to <cite>XEP-0248</cite> for details).</p>
<p>The service MUST validate that the entity making the request is authorized to set the subscription options for the subscribed entity. If the subscriber's JID is of the form &FULLJID;, a service MUST perform this check by comparing the &BAREJID; part of the two JIDs to ensure that they match. If the bare JID portions of the JIDs do not match and the requesting entity is not authorized to modify subscription options for the JID (e.g., because it is not a service-wide admin or authorized proxy), the service MUST return a &forbidden; error.</p> <p>The service MUST validate that the entity making the request is authorized to set the subscription options for the subscribed entity. If the subscriber's JID is of the form &FULLJID;, a service MUST perform this check by comparing the &BAREJID; part of the two JIDs to ensure that they match. If the bare JID portions of the JIDs do not match and the requesting entity is not authorized to modify subscription options for the JID (e.g., because it is not a service-wide admin or authorized proxy), the service MUST return a &forbidden; error.</p>
<example caption='Requesting entity does not have sufficient privileges to modify subscription options'><![CDATA[ <example caption='Requesting entity does not have sufficient privileges to modify subscription options'><![CDATA[
<iq type='error' <iq type='error'
@ -2326,7 +2323,7 @@ And by opposing end them?
]]></example> ]]></example>
</section4> </section4>
<section4 topic='Item Retrieval Not Supported' anchor='subscriber-retrieve-error-notsupported'> <section4 topic='Item Retrieval Not Supported' anchor='subscriber-retrieve-error-notsupported'>
<p>If the service or node does not support item retrieval (e.g., because the node is a collection node), the service MUST return a &feature; error to the subscriber, specifying a pubsub-specific error condition of &lt;unsupported/&gt; and a feature of "retrieve-items".</p> <p>If the service or node does not support item retrieval (e.g., because the node is a collection node as described in <cite>XEP-0248</cite>), the service MUST return a &feature; error to the subscriber, specifying a pubsub-specific error condition of &lt;unsupported/&gt; and a feature of "retrieve-items".</p>
<example caption='Item retrieval not supported'><![CDATA[ <example caption='Item retrieval not supported'><![CDATA[
<iq type='error' <iq type='error'
from='pubsub.shakespeare.lit' from='pubsub.shakespeare.lit'
@ -2689,7 +2686,7 @@ And by opposing end them?
]]></example> ]]></example>
</section4> </section4>
<section4 topic='Item Publication Not Supported' anchor='publisher-publish-error-notsupported'> <section4 topic='Item Publication Not Supported' anchor='publisher-publish-error-notsupported'>
<p>If the node does not support item publication (because it is a <link url='#collections'>Collection Node</link>), the service MUST return a &feature; error, specifying a pubsub-specific error condition of &lt;unsupported/&gt; and a feature of "publish".</p> <p>If the node does not support item publication (e.g., because it is a collection node as described in <cite>XEP-0248</cite>), the service MUST return a &feature; error, specifying a pubsub-specific error condition of &lt;unsupported/&gt; and a feature of "publish".</p>
<example caption='Node does not support item publication'><![CDATA[ <example caption='Node does not support item publication'><![CDATA[
<iq type='error' <iq type='error'
from='pubsub.shakespeare.lit' from='pubsub.shakespeare.lit'
@ -3191,7 +3188,7 @@ And by opposing end them?
</pubsub> </pubsub>
</iq> </iq>
]]></example> ]]></example>
<p>Note: When a service successfully creates a node on behalf of the requesting entity, it MUST return an IQ result. If the node creation request did not specify a NodeID and the service supports creation of instant nodes, the service MUST specify the created NodeID in the IQ result. Similarly, if the node creation request specified a NodeID but the service modified the NodeID before creating the node as described in the <link url='#collections'>Collection Nodes</link> section of this document, the service MUST also specify the modified node in the IQ result. In all other cases, the service MUST NOT specify the NodeID in the IQ result (since the node creator can determine which node was created by tracking the 'id' attribute that it specified for the IQ-set).</p> <p>Note: When a service successfully creates a node on behalf of the requesting entity, it MUST return an IQ result. If the node creation request did not specify a NodeID and the service supports creation of instant nodes, the service MUST specify the created NodeID in the IQ result. Similarly, if the node creation request specified a NodeID but the service modified the NodeID before creating the node (refer to <cite>XEP-0248</cite>), the service MUST also specify the modified node in the IQ result. In all other cases, the service MUST NOT specify the NodeID in the IQ result (since the node creator can determine which node was created by tracking the 'id' attribute that it specified for the IQ-set).</p>
</section3> </section3>
<section3 topic='Create a Node With Default Configuration' anchor='owner-create-default'> <section3 topic='Create a Node With Default Configuration' anchor='owner-create-default'>
<p>As explained above, each node type has its own default configuration. By asking the service to create a node with default configuration, the node creator accepts the default configuration. If the service allows node configuration, the owner may reconfigure the node after creating the node (as described in the <link url='#owner-configure'>Configure a Node</link> section of this document). In addition, a service MAY allow entities to determine the default configuration options for a given node type before creating a node (as described in the <link url='#owner-default'>Request Default Configurations</link> section of this document).</p> <p>As explained above, each node type has its own default configuration. By asking the service to create a node with default configuration, the node creator accepts the default configuration. If the service allows node configuration, the owner may reconfigure the node after creating the node (as described in the <link url='#owner-configure'>Configure a Node</link> section of this document). In addition, a service MAY allow entities to determine the default configuration options for a given node type before creating a node (as described in the <link url='#owner-default'>Request Default Configurations</link> section of this document).</p>
@ -3257,7 +3254,7 @@ And by opposing end them?
</error> </error>
</iq> </iq>
]]></example> ]]></example>
<p>(For error handling if the service does not support the specified node type, see the <link url='#collections'>Collection Node</link> section of this document.)</p> <p>(For error handling if the service does not support the specified node type, refer to <cite>XEP-0248</cite>.)</p>
</section3> </section3>
<section3 topic='Create and Configure a Node' anchor='owner-create-and-configure'> <section3 topic='Create and Configure a Node' anchor='owner-create-and-configure'>
<p>If an implementation allows node configuration (see the <link url='#owner-configure'>Configure a Node</link> section of this document), it SHOULD allow node creation requests to contain the desired node configuration in the node creation request.</p> <p>If an implementation allows node configuration (see the <link url='#owner-configure'>Configure a Node</link> section of this document), it SHOULD allow node creation requests to contain the desired node configuration in the node creation request.</p>
@ -3595,7 +3592,7 @@ And by opposing end them?
]]></example> ]]></example>
</section4> </section4>
<section4 topic='Success With Notifications' anchor='owner-configure-process-notify'> <section4 topic='Success With Notifications' anchor='owner-configure-process-notify'>
<p>If the "pubsub#notify_config" option is set to true, the service MUST send a notification of configuration change to all subscribers. (A service SHOULD support this option for leaf nodes and MUST support it for <link url='#collection'>Collection Nodes</link>.) If the node configuration is set to event notifications only, the notification MUST consist of an empty &lt;configuration/&gt; element whose 'node' attribute is set to the NodeID of the node; if the node configuration is set to full payloads, the &lt;configuration/&gt; element MUST in addition contain the node configuration as represented via the <strong>Data Forms</strong> protocol.</p> <p>If the "pubsub#notify_config" option is set to true, the service MUST send a notification of configuration change to all subscribers. (A service SHOULD support this option for leaf nodes and MUST support it for collection nodes as described in <cite>XEP-0248</cite>.) If the node configuration is set to event notifications only, the notification MUST consist of an empty &lt;configuration/&gt; element whose 'node' attribute is set to the NodeID of the node; if the node configuration is set to full payloads, the &lt;configuration/&gt; element MUST in addition contain the node configuration as represented via the <strong>Data Forms</strong> protocol.</p>
<example caption='Service sends configuration change notification (event notification only)'><![CDATA[ <example caption='Service sends configuration change notification (event notification only)'><![CDATA[
<message from='pubsub.shakespeare.lit' to='francisco@denmark.lit' id='foo'> <message from='pubsub.shakespeare.lit' to='francisco@denmark.lit' id='foo'>
<event xmlns='http://jabber.org/protocol/pubsub#event'> <event xmlns='http://jabber.org/protocol/pubsub#event'>
@ -3793,48 +3790,6 @@ And by opposing end them?
]]></example> ]]></example>
</section4> </section4>
</section3> </section3>
<section3 topic='Requesting Collection Node Configuration' anchor='owner-default-requestcollection'>
<p>The default configuration options may be different for a collection node vs. a leaf node. In order to specifically request the default configuration options for collection nodes, an entity MUST include a Data Form with a 'pubsub#node_type' field whose value is "collection" in the request (since the default value for the 'pubsub#node_type' field is "leaf").</p>
<example caption='Entity requests default configuration options for collection nodes'><![CDATA[
<iq type='get'
from='hamlet@denmark.lit/elsinore'
id='def2'>
<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
<default>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'>
<value>http://jabber.org/protocol/pubsub#node_config</value>
</field>
<field var='pubsub#node_type'><value>collection</value></field>
</x>
</default>
</pubsub>
</iq>
]]></example>
<p>If the service does not support collection nodes, it MUST return a &feature; error, specifying a pubsub-specific error condition of &lt;unsupported/&gt; and a feature of "collections".</p>
<example caption='Service does not support collection nodes'><![CDATA[
<iq type='error'
from='pubsub.shakespeare.lit'
to='hamlet@denmark.lit/elsinore'
id='def2'>
<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
<default>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'>
<value>http://jabber.org/protocol/pubsub#node_config</value>
</field>
<field var='pubsub#node_type'><value>collection</value></field>
</x>
</default>
</pubsub>
<error type='cancel'>
<feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
<unsupported xmlns='http://jabber.org/protocol/pubsub#errors'
feature='collections'/>
</error>
</iq>
]]></example>
</section3>
</section2> </section2>
<section2 topic='Delete a Node' anchor='owner-delete'> <section2 topic='Delete a Node' anchor='owner-delete'>
<p>If a service supports node creation, it MUST support node deletion. If an implementation persists items, it MUST remove all items from persistent storage before the node itself is deleted.</p> <p>If a service supports node creation, it MUST support node deletion. If an implementation persists items, it MUST remove all items from persistent storage before the node itself is deleted.</p>
@ -3872,13 +3827,12 @@ And by opposing end them?
</event> </event>
</message> </message>
]]></example> ]]></example>
<p>If the node to be deleted is a collection node, the service should follow the recommendations provided under <link url='#collections-delete'>Collection Node Deletion</link>.</p>
</section3> </section3>
<section3 topic='Error Cases' anchor='owner-delete-error'> <section3 topic='Error Cases' anchor='owner-delete-error'>
<p>There are several reasons why the node deletion request might fail:</p> <p>There are several reasons why the node deletion request might fail:</p>
<ol> <ol>
<li>The requesting entity does not have sufficient privileges to delete the node.</li> <li>The requesting entity does not have sufficient privileges to delete the node.</li>
<li>The node is the root collection node, which cannot be deleted.</li> <li>The node is the root collection node, which cannot be deleted (see <cite>XEP-0248</cite>).</li>
<li>The specified node does not exist.</li> <li>The specified node does not exist.</li>
</ol> </ol>
<p>These error cases are described more fully in the following sections.</p> <p>These error cases are described more fully in the following sections.</p>
@ -3895,22 +3849,6 @@ And by opposing end them?
<error type='auth'> <error type='auth'>
<forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error> </error>
</iq>
]]></example>
</section4>
<section4 topic='Root Collection Node' anchor='owner-delete-error-root'>
<p>If the requesting entity attempts to delete the root collection node, the service MUST return a &notallowed; error.</p>
<example caption='Node is the root'><![CDATA[
<iq type='error'
from='pubsub.shakespeare.lit'
to='hamlet@denmark.lit/elsinore'
id='delete1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
<delete/>
</pubsub>
<error type='cancel'>
<not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq> </iq>
]]></example> ]]></example>
</section4> </section4>
@ -4012,7 +3950,7 @@ And by opposing end them?
]]></example> ]]></example>
</section4> </section4>
<section4 topic='Node Does Not Persist Items' anchor='owner-purge-error-nopersist'> <section4 topic='Node Does Not Persist Items' anchor='owner-purge-error-nopersist'>
<p>If the service or node does not persist items (e.g., because the node is a collection node), it MUST return a &feature; error, specifying a pubsub-specific error condition of &lt;unsupported/&gt; and a feature of "persistent-items".</p> <p>If the service or node does not persist items (e.g., because the node is a collection node as described in <cite>XEP-0248</cite>), it MUST return a &feature; error, specifying a pubsub-specific error condition of &lt;unsupported/&gt; and a feature of "persistent-items".</p>
<example caption='Node is not configured for persistent items'><![CDATA[ <example caption='Node is not configured for persistent items'><![CDATA[
<iq type='error' <iq type='error'
from='pubsub.shakespeare.lit' from='pubsub.shakespeare.lit'
@ -4102,9 +4040,9 @@ And by opposing end them?
from='pubsub.shakespeare.lit' from='pubsub.shakespeare.lit'
to='horatio@denmark.lit' to='horatio@denmark.lit'
id='approvalnotify1'> id='approvalnotify1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'> <event xmlns='http://jabber.org/protocol/pubsub#event'>
<subscription node='princely_musings' jid='horatio@denmark.lit' subscription='subscribed'/> <subscription node='princely_musings' jid='horatio@denmark.lit' subscription='subscribed'/>
</pubsub> </event>
</message> </message>
]]></example> ]]></example>
<p>In order to deny the request, the owner shall submit the form and set the "pubsub#allow" field to a value of "0" or "false"; as above, the message MUST reflect the 'id' attribute originally provided.</p> <p>In order to deny the request, the owner shall submit the form and set the "pubsub#allow" field to a value of "0" or "false"; as above, the message MUST reflect the 'id' attribute originally provided.</p>
@ -4783,678 +4721,6 @@ And by opposing end them?
</section2> </section2>
</section1> </section1>
<section1 topic='Collection Nodes' anchor='collections'>
<p>A pubsub service MAY support collection nodes as well as leaf nodes. Collections enable nodes to be grouped together in many ways. A collection node MUST contain only leaf nodes and/or other collection nodes (similar to the way in which a file system directory can contain both files and subdirectories) and MUST NOT contain published items (therefore a collection MUST NOT support the "publish" feature or related features such as "persistent-items"). If collections are supported, a service MUST advertise that fact in its "disco#info" responses by including a feature of "pubsub#collections" and MUST support service discovery of child nodes as described in the <link url='#entity-nodes'>Discover Nodes</link> section of this document.</p>
<section2 topic='Node Relationship Models' anchor='collections-models'>
<p>This section provides background information about collection nodes, with insights from graph theory. <note>See <link url='http://en.wikipedia.org/wiki/Graph_(mathematics)'>http://en.wikipedia.org/wiki/Graph_(mathematics)</link>.</note> The intended result is a clearer vocabulary about particular deployment scenarios. The terminology introduced in this section is used mainly in the discussion of <link url='collections-delete'>collection node deletion</link>.</p>
<p>In terms of graph theory, the set of nodes hosted at a pubsub service is a directed acyclic graph. <note>See <link url='http://en.wikipedia.org/wiki/Directed_acyclic_graph'>http://en.wikipedia.org/wiki/Directed_acyclic_graph</link>.</note> The particular graph types can be further described as follows:</p>
<ol>
<li>If there are no collection nodes, we say that the graph is simply a <strong>flat set</strong> of nodes without connections because there are no arcs between nodes, i.e., no node is the direct predecessor of another node (here we use the less formall phrase that no node is the parent of any other child node).</li>
<li>If there may be multiple paths between between any two given nodes (where the path may include intermediate collection nodes), the graph is a <strong>Directed Acyclic Graph</strong> or "DAG" <note>See <link url='http://en.wikipedia.org/wiki/Directed_acyclic_graph'>http://en.wikipedia.org/wiki/Directed_acyclic_graph</link>.</note> because a given node may be the child of multiple parents.</li>
<li>If there is only one path between any two given nodes (where the path may include intermediate collection nodes), the graph is a <strong>Tree</strong> <note>See <link url='http://en.wikipedia.org/wiki/Tree_(graph_theory)'>http://en.wikipedia.org/wiki/Tree_(graph_theory)</link>.</note> because a given node may be the child of only one collection node.</li>
<li>If there is a root collection node but there are no internal collection nodes, we say informally that the graph has a <strong>depth</strong> of 1 because all of the connections from leaf nodes to the root collection node are direct (i.e., each connection is an arc); this case is equivalent to a flat set with a root collection node and is typically uninteresting.</li>
<li>If there is a root collection node and there are internal collection nodes, we say that the graph has <strong>infinite depth</strong> because there is an unbounded number of arcs between each leaf node and the root collection node; this case is more interesting than a graph of depth=1 since it enables a wide range of trees and hierarchies.</li>
<li>In a tree with collection nodes, deletion of a collection node automatically results in destruction of the arcs to that collection node from leaf nodes or other collection nodes because a child can have only one parent; in this case we say that a child node has a <strong>dependency</strong> on its parent and that the tree is a <strong>Strict Hierarchy</strong>. (This is similar to a strictly hierarchical file system, in which deletion of a directory results in deletion of all its file and subdirectories.)</li>
<li>In a DAG with collection nodes, deletion of a collection node does not automatically result in destruction of the arcs to that collection node from leaf nodes or other collection nodes because a child can have multiple parents (but if the last parent is deleted, the last remaining arc is destroyed); in this case we say that the tree is a <strong>Loose Hierarchy</strong>. (This is similar to a loosely hierarchical file system that is mostly hierarchical but that allows multiple soft links.)</li>
<li>If a graph is made up of directed acyclic graphs but there is no single root collection node for all the DAGs, we say that the graph is a <strong>Dag Set</strong> (i.e., a set of directed acyclic graphs).</li>
<li>If a graph is made up of trees but there is no single root collection node for all the trees, the graph is a <strong>Forest</strong> (i.e., a set of trees).</li>
<li>If each tree in a forest is a Strict Hierarchy, we say that the graph is a <strong>Strict Hierarchy Set</strong>.</li>
<li>If each DAG in a set is a Loose Hierarchy, we say that the graph is a <strong>Loose Hierarchy Set</strong>.</li>
</ol>
<p>Finally, in XMPP pubsub, all graphs are <strong>oriented</strong> because any two collection nodes cannot have a bidirectional relationship (i.e., if collection node #1 is a direct predecessor of collection node #2 then #2 cannot also be a direct predecessor of #1).</p>
<p>This terminology is summarized in the following table.</p>
<table caption='Node Relationship Models'>
<tr>
<th>Model</th>
<th>Description</th>
<th>Root Node</th>
<th>Multiple Parents</th>
<th>Node Dependency</th>
<th>Depth</th>
</tr>
<tr>
<td>Flat Set</td>
<td>A set of nodes with no parent-child relationships (i.e., there are no collection nodes).</td>
<td>No</td>
<td>N/A</td>
<td>No</td>
<td>0 (zero)</td>
</tr>
<tr>
<td>Directed Acyclic Graph (DAG)</td>
<td>A set of nodes with parent-child relationships, where a child node can have more than one parent.</td>
<td>Yes</td>
<td>Yes</td>
<td>No</td>
<td>1 or infinite</td>
</tr>
<tr>
<td>Dag Set</td>
<td>A set of DAGs with no root node.</td>
<td>No</td>
<td>Yes</td>
<td>No</td>
<td>1 or infinite</td>
</tr>
<tr>
<td>Tree</td>
<td>A set of nodes with parent-child relationships, where a node can be the child of only one parent.</td>
<td>Yes</td>
<td>No</td>
<td>No</td>
<td>1 or infinite</td>
</tr>
<tr>
<td>Forest</td>
<td>A set of trees with no root node.</td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>1 or infinite</td>
</tr>
<tr>
<td>Strict Hierarchy</td>
<td>An infinite tree in which a child node can have only one parent and is dependent on its parent.</td>
<td>Yes</td>
<td>No</td>
<td>Yes</td>
<td>Infinite</td>
</tr>
<tr>
<td>Strict Hierarchy Set</td>
<td>A set of strict hierarchies with no root node.</td>
<td>No</td>
<td>No</td>
<td>Yes</td>
<td>Infinite</td>
</tr>
<tr>
<td>Loose Hierarchy</td>
<td>An infinite DAG in which a child node can have multiple parents but cannot exist without at least one parent.</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
<td>Infinite</td>
</tr>
<tr>
<td>Loose Hierarchy Set</td>
<td>A set of loose hierarchies with no root node.</td>
<td>No</td>
<td>Yes</td>
<td>Yes</td>
<td>Infinite</td>
</tr>
</table>
</section2>
<section2 topic='Subscribe to a Collection Node' anchor='collections-subscribe'>
<p>A service that implements collection nodes SHOULD allow entities to subscribe to collection nodes (subject to access models and local security policies).</p>
<p>In addition to the subscription configuration options already defined, there are two subscription configuration options specific to collection nodes:</p>
<ul>
<li>
<p><strong>pubsub#subscription_type</strong></p>
<p>This subscription option enables the subscriber to subscribe either to items or to nodes.</p>
<p>If the subscription type is "items", the subscriber shall be notified whenever any node contained in the collection generates a notification (e.g., when an item is published or deleted), as modified by the value of the "pubsub#subscription_depth" option.</p>
<p>If the subscription type is "nodes", the subscriber shall be notified whenever a new node is added to the collection, as modified by the value of the "pubsub#subscription_depth" option.</p>
<p>The default value of this subscription option MUST be "nodes".</p>
</li>
<li>
<p><strong>pubsub#subscription_depth</strong></p>
<p>This subscription option enables the subscriber to specify whether it wants to receive notifications only from first-level children of the collection (a value of "1") or from all descendents (a value of "all").</p>
<p>For subscriptions of type "items", this enables the subscriber to be informed only when an item is published to a leaf node that is a direct child of the collection node to which it has subscribed, or to be informed whenever an item is published to any leaf node in the "tree" that begins at the level of the collection to which it has subscribed.</p>
<p>For subscriptions of type "nodes", this enables the subscriber to be informed only when a new node is added in the specific collection to which it has subscribed, or to be informed whenever a node is added anywhere in the "tree" that begins at the level of the collection to which it has subscribed.</p>
<p>The default value of this subscription option MUST be "1".</p>
</li>
</ul>
<p>In order to subscribe to a collection node, an entity MUST send a subscription request to the node; the subscription request MAY include subscription options, but this is not strictly necessary (especially if the entity does not wish to override the default settings for the "pubsub#subscription_type" and "pubsub#subscription_depth" options).</p>
<example caption='Entity subscribes to a collection node (no configuration)'><![CDATA[
<iq type='set'
from='francisco@denmark.lit/barracks'
to='pubsub.shakespeare.lit'
id='collsub1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<subscribe jid='francisco@denmark.lit'
node='blogs'/>
</pubsub>
</iq>
]]></example>
<p>The subscriber will now receive notification of new first-level nodes created within the "blogs" collection.</p>
<example caption='Entity subscribes to a collection node (with configuration)'><![CDATA[
<iq type='set'
from='francisco@denmark.lit/barracks'
to='pubsub.shakespeare.lit'
id='collsub2'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<subscribe jid='francisco@denmark.lit'
node='blogs'/>
<options>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'>
<value>http://jabber.org/protocol/pubsub#subscribe_options</value>
</field>
<field var='pubsub#subscription_type'>
<value>items</value>
</field>
<field var='pubsub#subscription_depth'>
<value>all</value>
</field>
</x>
</options>
</pubsub>
</iq>
]]></example>
<p>The subscriber will now receive item notifications from nodes at any depth within the "blogs" collection.</p>
<p>Depending on the nature of the node "tree", a subscription type of "items" and depth of "all" may result in an extremely large number of notifications. Therefore, a service MAY disallow such a combination of subscription options, in which case it MUST return a &notallowed; error to the requesting entity.</p>
<p>A service MAY allow an entity to subscribe to a collection node in two ways, once with a subscription of type "nodes" (to receive notification of any new nodes added to the collection or the entire tree) and once with a subscription of type "items" (to receive all items published within the tree). However, a service SHOULD NOT allow an entity to subscribe twice to a collection node (once with a subscription depth of "1" and once with a subscription depth of "all") for the same subscription type, since two such subscriptions are unnecessary (a depth of "all" includes by definition a depth of "1"); in this case the service SHOULD return a &conflict; error to the requesting entity.</p>
</section2>
<section2 topic='Root Collection Node' anchor='collections-root'>
<p>A service that implements collections SHOULD support a root collection. The root collection shall be identified by the lack of a node identifier (i.e., the address of the pubsub service itself, such as "pubsub.shakespeare.lit").</p>
<p>Subscribing to this node with a subscription of type "nodes" and a depth of "1" enables an entity to be notified whenever a new first-level node is created at the pubsub service. Subscribing to this node with a subscription of type "nodes" and a depth of "all" enables an entity to be notified whenever a new node is created anywhere at the pubsub service.</p>
<example caption='Entity subscribes to the root collection node'><![CDATA[
<iq type='set'
from='francisco@denmark.lit/barracks'
to='pubsub.shakespeare.lit'
id='root1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<subscribe jid='francisco@denmark.lit'/>
</pubsub>
</iq>
]]></example>
<p>If the root collection node is configured to send notification of node associations and disassociations, the service shall send an event that contains a &lt;collection/&gt; element whose 'node' attribute specifies the NodeID of the collection (in this case the NodeID is empty to signify that the collection is the root collection); this element in turn contains an &lt;associate/&gt; element whose 'node' attribute specifies the NodeID of node that has been associated with the collection.</p>
<example caption='Notification of node association'><![CDATA[
<message from='pubsub.shakespeare.lit'
to='francisco@denmark.lit'
id='newnode1'>
<event xmlns='http://jabber.org/protocol/pubsub#event'>
<collection node='some-collection'>
<associate node='new-node-id'>
</collection>
</event>
</message>
]]></example>
<p>The notification event MAY also include the node meta-data, formatted using the <strong>Data Forms</strong> protocol.</p>
<example caption='Notification of node association'><![CDATA[
<message from='pubsub.shakespeare.lit'
to='francisco@denmark.lit'
id='newnode2'>
<event xmlns='http://jabber.org/protocol/pubsub#event'>
<collection node=''>
<associate node='new-node-id'>
<x xmlns='jabber:x:data' type='result'>
<field var='FORM_TYPE' type='hidden'>
<value>http://jabber.org/protocol/pubsub#meta-data</value>
</field>
<field var='pubsub#creation_date'><var>2003-07-29T22:56Z</var></field>
<field var='pubsub#creator'><var>hamlet@denmark.lit</var></field>
<field var='pubsub#description'><var>Atom feed for my blog.</var></field>
<field var='pubsub#language'><var>en</var></field>
<field var='pubsub#contact'><value>bard@shakespeare.lit</value></field>
<field var='pubsub#owner'><value>hamlet@denmark.lit</value></field>
<field var='pubsub#title'><var>Princely Musings (Atom).</var></field>
<field var='pubsub#type'><value>http://www.w3.org/2005/Atom</value></field>
</x>
</node>
</collection>
</event>
</message>
]]></example>
</section2>
<section2 topic='Create a New Collection Node' anchor='collections-createnode'>
<p>To create a new collection node, the requesting entity MUST include a Data Form containing a 'pubsub#node_type' field whose &lt;value/&gt; is "collection".</p>
<example caption='Entity requests a new collection node'><![CDATA[
<iq type='set'
from='bard@shakespeare.lit/globe'
to='pubsub.shakespeare.lit'
id='create3'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<create node='announcements'/>
<configure>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'>
<value>http://jabber.org/protocol/pubsub#node_config</value>
</field>
<field var='pubsub#node_type'><value>collection</value></field>
</x>
</configure>
</pubsub>
</iq>
]]></example>
<example caption='Service responds with success'><![CDATA[
<iq type='result'
from='pubsub.shakespeare.lit'
to='bard@shakespeare.lit/globe'
id='create3'/>
]]></example>
<p>In addition to the errors already defined for leaf node creation, there are several reasons why the collection node creation request might fail:</p>
<ol>
<li>The service does not support collection nodes.</li>
<li>The service does not support creation of collection nodes.</li>
<li>The requesting entity does not have sufficient privileges to create collection nodes.</li>
</ol>
<p>These error cases are described more fully in the following sections.</p>
<p>If the service does not support collection nodes, it MUST respond with a &feature; error, specifying a pubsub-specific error condition of &lt;unsupported/&gt; and a feature of "collections".</p>
<example caption='Service does not support collection nodes'><![CDATA[
<iq type='error'
from='hamlet@denmark.lit/elsinore'
to='pubsub.shakespeare.lit'
id='config1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
<configure node='princely_musings'/>
</pubsub>
<error type='cancel'>
<feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
<unsupported xmlns='http://jabber.org/protocol/pubsub#errors'
feature='collections'/>
</error>
</iq>
]]></example>
<p>If the service supports collection nodes but does not allow new collection nodes to be created, it MUST respond with a &notallowed; error.</p>
<example caption='Service does not allow creation of collection nodes'><![CDATA[
<iq type='error'
from='hamlet@denmark.lit/elsinore'
to='pubsub.shakespeare.lit'
id='config1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
<configure node='princely_musings'/>
</pubsub>
<error type='cancel'>
<not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
]]></example>
<p>If the requesting entity has insufficient privileges to create new collections, the service MUST respond with a &forbidden; error.</p>
<example caption='Requesting entity has insufficient privileges to create collection nodes'><![CDATA[
<iq type='error'
from='pubsub.shakespeare.lit'
to='hamlet@denmark.lit/elsinore'
id='config1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
<configure node='princely_musings'/>
</pubsub>
<error type='auth'>
<forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
]]></example>
<p>A service MAY offer some node configuration options that are specific to collection nodes and not provided in configuration forms related to leaf nodes. The following are RECOMMENDED:</p>
<ul>
<li>pubsub#children_association_policy -- the policy regarding who may associate child nodes with the collection (values: all, owner, whitelist).</li>
<li>pubsub#children_association_whitelist -- the whitelist of entities that may associate child nodes with the collection.</li>
<li>pubsub#children_max -- the maximum number of child nodes that may be associated with a collection.</li>
</ul>
</section2>
<section2 topic='Create a Node Associated with a Collection' anchor='collections-createassociated'>
<section3 topic='Request' anchor='collections-createassociated-request'>
<p>To create a new node and associate it with an existing collection, the node configuration protocol MUST be used in the node creation request (see the <link url='#owner-create-and-configure'>Create and Configure a Node</link> section of this document). In order to specify the associated collection(s), the form MUST include a 'pubsub#collection' field.</p>
<p>Note: Inclusion of the node configuration form is not necessary if the node is being created as a first-level child of the root collection node, since every such child is automatically affiliated with the root collection node (if any).</p>
<p>Note: For the protocol used to associate an existing node with a collection, refer to the <link url='#collections-associate'>Associate an Existing Node with a Collection</link> section of this document.</p>
<example caption='Entity creates a new node associated with a collection'><![CDATA[
<iq type='set'
from='bard@shakespeare.lit/globe'
to='pubsub.shakespeare.lit'
id='create4'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<create node='plays'/>
<configure>
<x xmlns='jabber:x:data' type='submit'>
<field var='pubsub#collection'><value>announcements</value></field>
</x>
</configure>
</pubsub>
</iq>
]]></example>
<p>Note: If the node is a collection node and the requesting entity wishes to request the default configuration, the requesting entity MUST include <em>only</em> the "pubsub#collection" and "pubsub#node_type" fields in the configuration form.</p>
</section3>
<section3 topic='Success Case' anchor='collections-createassociated-success'>
<p>If no error occurs, the service MUST create the node and associate it with the collection.</p>
</section3>
<section3 topic='Error Cases' anchor='collections-createassociated-error'>
<p>There are several reasons why the request might fail:</p>
<ol>
<li>The request specified more than one collection node, but the service allows a node to be associated with only one collection node.</li>
<li>The requesting entity does not have sufficient privileges to associate a node with the specified collection node.</li>
<li>No additional nodes can be associated with the collection node.</li>
<li>The specified collection node is actually a leaf node.</li>
<li>The specified collection node does not exist.</li>
</ol>
<p>These error cases are described more fully in the following sections.</p>
<section4 topic='Only One Collection Node' anchor='collections-createassociated-error-onenode'>
<p>An implementation MAY allow a node to be associated with more than one collection node and therefore MAY specify a type of "text-multi" for the "pubsub#collection" field. However, in order to reduce the complexity of implementation, it is RECOMMENDED to allow only one parent collection node for each node and therefore it is RECOMMENDED to specify a type of "text-single" for the "pubsub#collection" field. If a service supports associating a node with multiple collections, it MUST advertise support for the "multi-collection" feature (if that feature is not advertised, entities SHOULD assume that the service allows a node to be associated with only one collection). If the request specifies more than one collection node but the service allows a node to be associated with only one collection node, the service MUST return a &badrequest; error.</p>
<example caption='Too many collection nodes'><![CDATA[
<iq type='error'
from='pubsub.shakespeare.lit'
to='bard@shakespeare.lit/globe'
id='create4'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<create node='plays'/>
<configure>
<x xmlns='jabber:x:data' type='submit'>
<field var='pubsub#collection'>
<value>announcements</value>
<value>news</value>
</field>
<field var='pubsub#node_type'>
<value>collection</value>
</field>
</x>
</configure>
</pubsub>
<error type='modify'>
<bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
]]></example>
</section4>
<section4 topic='Insufficient Privileges' anchor='collections-createassociated-error-forbidden'>
<p>If the requesting entity does not have sufficient privileges to associate a node with the specified collection node, the service MUST return a &forbidden; error.</p>
<example caption='Insufficient privileges'><![CDATA[
<iq type='error'
from='pubsub.shakespeare.lit'
to='bard@shakespeare.lit/globe'
id='create4'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<create node='plays'/>
<configure>
<x xmlns='jabber:x:data' type='submit'>
<field var='pubsub#collection'><value>announcements</value></field>
</x>
</configure>
</pubsub>
<error type='auth'>
<forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
]]></example>
</section4>
<section4 topic='No More Nodes' anchor='collections-createassociated-error-nomore'>
<p>If no additional nodes can be associated with the collection node because a configurable limit of associated nodes has been reached, the service MUST return a &conflict; error, which SHOULD also include a pubsub-specific error condition of &lt;max-nodes-exceeded/&gt;.</p>
<example caption='Associated node limit reached'><![CDATA[
<iq type='error'
from='pubsub.shakespeare.lit'
to='bard@shakespeare.lit/globe'
id='create4'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<create node='plays'/>
<configure>
<x xmlns='jabber:x:data' type='submit'>
<field var='pubsub#collection'><value>announcements</value></field>
</x>
</configure>
</pubsub>
<error type='cancel'>
<conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
<max-nodes-exceeded xmlns='http://jabber.org/protocol/pubsub#errors'/>
</error>
</iq>
]]></example>
</section4>
<section4 topic='Leaf Node' anchor='collections-createassociated-error-leaf'>
<p>If the specified collection node is actually a leaf node, the service MUST return an &notallowed; error.</p>
<example caption='Collection node is actually a leaf node'><![CDATA[
<iq type='error'
from='pubsub.shakespeare.lit'
to='bard@shakespeare.lit/globe'
id='create4'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<create node='plays'/>
<configure>
<x xmlns='jabber:x:data' type='submit'>
<field var='pubsub#collection'><value>announcements</value></field>
</x>
</configure>
</pubsub>
<error type='cancel'>
<not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
]]></example>
</section4>
<section4 topic='Node Does Not Exist' anchor='collections-createassociated-error-node'>
<p>If the specified collection node does not exist, the service MUST return an &notfound; error.</p>
<example caption='No such collection node'><![CDATA[
<iq type='error'
from='pubsub.shakespeare.lit'
to='bard@shakespeare.lit/globe'
id='create4'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<create node='plays'/>
<configure>
<x xmlns='jabber:x:data' type='submit'>
<field var='pubsub#collection'><value>announcements</value></field>
</x>
</configure>
</pubsub>
<error type='cancel'>
<item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
]]></example>
</section4>
</section3>
</section2>
<section2 topic='Collection Node Deletion' anchor='collections-delete'>
<p>Deletion of a collection node can introduce a large number of changes to the system, depending on the <link url='#collections-models'>node relationship model</link> of the deployed system. This section describes recommended handling of deletion requests in the context of collection nodes.</p>
<section3 topic='Directed Acyclic Graph' anchor='collections-delete-dag'>
<p>When the graph of the pubsub system is a Directed Acyclic Graph, a child node can have more than one parent, which may be the root collection node. Therefore, when a node owner deletes a collection node the service MUST behave as follows:</p>
<ul>
<li>If a child node will still have at least one other parent after deletion of the collection node, the service MUST NOT delete the child node but instead MUST simply sever the relationship between the deleted collection node and the child node.</li>
<li>If a child node will have no other parents after deletion of the collection node, the service MUST associate any orphaned child with the root collection node.</li>
</ul>
</section3>
<section3 topic='Dag Set' anchor='collections-delete-dagset'>
<p>When the graph of the pubsub system is a Dag Set, a child node can have more than one parent but there is no root collection node. Therefore, when a node owner deletes a collection node the service MUST behave as follows:</p>
<ul>
<li>If a child node will still have at least one other parent after deletion of the collection node, the service MUST NOT delete the child node but instead MUST simply sever the relationship between the deleted collection node and the child node.</li>
<li>If a child node will have no other parents after deletion of the collection node, the service MUST associate any orphaned child with no other node.</li>
</ul>
</section3>
<section3 topic='Tree' anchor='collections-delete-tree'>
<p>When the graph of the pubsub system is a Tree, a child node can have only one parent, which may be the root collection node. Therefore, when a node owner deletes a collection node the service MUST behave as follows:</p>
<ul>
<li>The service MUST associate any orphaned child with the root collection node.</li>
</ul>
</section3>
<section3 topic='Forest' anchor='collections-delete-forest'>
<p>When the graph of the pubsub system is a Forest, a child node can have only one parent but there is no root collection node. Therefore, when a node owner deletes a collection node the service MUST behave as follows:</p>
<ul>
<li>The service MUST associate any orphaned child with no other node.</li>
</ul>
</section3>
<section3 topic='Strict Hierarchy or Strict Hierarchy Set' anchor='collections-delete-strict'>
<p>When the graph of the pubsub system is a Strict Hierarchy or a Strict Hierarchy Set, a child node can have only one parent node and cannot exist without its parent. Therefore, when a node owner deletes a collection node the service MUST behave as follows:</p>
<ul>
<li>The service SHOULD delete any orphaned child(ren).</li>
</ul>
<p>Note: This action may introduce cascading changes, since deletion of a child will result in deletion of any grandchildren, great-grandchildren, etc. A service MAY refuse to allow deletion of a collection node if doing so will result in an excessive load on the system. If it so refuses, it MUST return a &constraint; error.</p>
</section3>
<section3 topic='Loose Hierarchy or Loose Hierarchy Set' anchor='collections-delete-loose'>
<p>When the graph of the pubsub system is a Loose Hierarchy or a Loose Hierarchy Set, a child node can have multiple parent nodes but a child node cannot exist without at least one parent node. Therefore, when a node owner deletes a collection node the service MUST behave as follows:</p>
<ul>
<li>If a child node will still have at least one other parent after deletion of the collection node, the service MUST NOT delete the child node but instead MUST simply sever the relationship between the deleted collection node and the child node.</li>
<li>If a child node will have no other parents after deletion of the collection node, the service SHOULD delete any orphaned child(ren).</li>
</ul>
<p>Note: This action may introduce cascading changes, since deletion of a child will result in deletion of any grandchildren, great-grandchildren, etc. A service MAY refuse to allow deletion of a collection node if doing so will result in an excessive load on the system. If it so refuses, it MUST return a &constraint; error.</p>
</section3>
</section2>
<section2 topic='Associate an Existing Node with a Collection' anchor='collections-associate'>
<p>Although a node can be associated with a collection when it is created (as described above), it can also be associated with a collection after it has been created. This can be done in two ways:</p>
<ul>
<li>By modifying the node's "pubsub#collection" configuration field.</li>
<li>By modifying the collection node's "pubsub#children" configuration field.</li>
</ul>
<p>These methods are described below.</p>
<p>In order to modify the (child) node's "pubsub#collection" configuration field, the owner of the node shall submit a request to edit the node's configuration, receive a configuration form from the service, and then submit a modified configuration form:</p>
<example caption='Node owner modifies node configuration'><![CDATA[
<iq type='set'
from='hamlet@denmark.lit/elsinore'
to='pubsub.shakespeare.lit'
id='associate1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
<configure node='princely_musings'>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'>
<value>http://jabber.org/protocol/pubsub#node_config</value>
</field>
...
<field var='pubsub#collection'><value>blogs</value></field>
...
</x>
</configure>
</pubsub>
</iq>
]]></example>
<p>Note: To associate a node with the root collection node, the node owner MUST submit an empty &lt;value/&gt; element within the 'pubsub#collection' field.</p>
<p>In order to modify the (parent) node's "pubsub#children" configuration field, the owner of the node shall submit a request to edit the node's configuration, receive a configuration form from the service, and then submit a modified configuration form:</p>
<example caption='Node owner modifies node configuration'><![CDATA[
<iq type='set'
from='bard@shakespeare.lit/globe'
to='pubsub.shakespeare.lit'
id='associate2'>
<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
<configure node='blogs'>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'>
<value>http://jabber.org/protocol/pubsub#node_config</value>
</field>
...
<field var='pubsub#children'>
<value>princely_musings</value>
<value>kingly_ravings</value>
<value>starcrossed_stories</value>
<value>moorish_meanderings</value>
</field>
...
</x>
</configure>
</pubsub>
</iq>
]]></example>
<p>If the collection node is configured to send notification of node associations and disassociations, the service shall send an event that contains a &lt;collection/&gt; element whose 'node' attribute specifies the NodeID of the collection; this element in turn contains an &lt;associate/&gt; element whose 'node' attribute specifies the NodeID of node that has been associated with the collection.</p>
<example caption='Notification of node association'><![CDATA[
<message from='pubsub.shakespeare.lit'
to='francisco@denmark.lit'
id='newnode3'>
<event xmlns='http://jabber.org/protocol/pubsub#event'>
<collection node='some-collection'>
<associate node='new-node-id'>
</collection>
</event>
</message>
]]></example>
<p>If an entity attempts to associate a node with a collection in a way that would violate the <link url='#collections-models'>node relationship model</link> (e.g., adding a second parent to a node in a Tree or Strict Hierarchy or making a child a new parent of its existing parent or other predecessor and thus violating the orientation of the graph), the service MUST return a &conflict; error.</p>
</section2>
<section2 topic='Disassociate a Node from a Collection' anchor='collections-disassociate'>
<p>A node can be disassociated from a collection after it has been associated (whether at creation time or afterward). This can be done in two ways:</p>
<ul>
<li>By modifying the node's "pubsub#collection" configuration field.</li>
<li>By modifying the collection node's "pubsub#children" configuration field.</li>
</ul>
<p>These methods are described below.</p>
<p>In order to modify the (child) node's "pubsub#collection" configuration field, the owner of the node shall submit a request to edit the node's configuration, receive a configuration form from the service, and then submit a modified configuration form:</p>
<example caption='Node owner modifies node configuration'><![CDATA[
<iq type='set'
from='hamlet@denmark.lit/elsinore'
to='pubsub.shakespeare.lit'
id='associate1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
<configure node='princely_musings'>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'>
<value>http://jabber.org/protocol/pubsub#node_config</value>
</field>
...
<field var='pubsub#collection'></field>
...
</x>
</configure>
</pubsub>
</iq>
]]></example>
<p>Note: To disassociate the node from all collection nodes, the node owner MUST submit an empty &lt;field/&gt; element for the 'pubsub#collection' field as shown in the foregoing example.</p>
<p>Note: To disassociate the node from the root collection node, the node owner MUST submit an empty &lt;value/&gt; element within the 'pubsub#collection' field as shown in the foregoing example.</p>
<p>In order to modify the (parent) node's "pubsub#children" configuration field, the owner of the node shall submit a request to edit the node's configuration, receive a configuration form from the service, and then submit a modified configuration form:</p>
<example caption='Node owner modifies node configuration'><![CDATA[
<iq type='set'
from='bard@shakespeare.lit/globe'
to='pubsub.shakespeare.lit'
id='associate2'>
<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
<configure node='blogs'>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'>
<value>http://jabber.org/protocol/pubsub#node_config</value>
</field>
...
<field var='pubsub#children'>
<value>kingly_ravings</value>
<value>starcrossed_stories</value>
<value>moorish_meanderings</value>
</field>
...
</x>
</configure>
</pubsub>
</iq>
]]></example>
<p>If the collection node is configured to send notification of node associations and disassociations, the service shall send an event that contains a &lt;collection/&gt; element whose 'node' attribute specifies the NodeID of the collection; this element in turn contains a &lt;disassociate/&gt; element whose 'node' attribute specifies the NodeID of node that has been disassociated from the collection.</p>
<example caption='Notification of node disassociation'><![CDATA[
<message from='pubsub.shakespeare.lit'
to='francisco@denmark.lit'
id='oldnode1'>
<event xmlns='http://jabber.org/protocol/pubsub#event'>
<collection node='some-collection'>
<disassociate node='new-node-id'>
</collection>
</event>
</message>
]]></example>
<p>If a node is disassociated from a collection node and a new association is not formed, the implementation MAY associate the node with the root collection node or associate it with no collection node.</p>
<p>Note: The combination of associating a node with one collection and disassociating the same node from another collection can be used to move a node from one collection to another.</p>
</section2>
<section2 topic='Generating Publish Notifications for Collections' anchor='collections-notify'>
<p>If an item is published to a node which is also included by a collection, and an entity is subscribed to that collection with a subscription type of "items", then the notifications generated by the service MUST contain additional information. The &ITEMS; element contained in the notification message MUST specify the node identifier of the node that generated the notification (not the collection) and the &ITEM; element MUST contain a SHIM header that specifies the node identifier of the collection.</p>
<example caption='Subscribers receive notifications from a collection'><![CDATA[
<message to='francisco@denmark.lit' from='pubsub.shakespeare.lit'>
<event xmlns='http://jabber.org/protocol/pubsub#event'>
<items node='princely_musings'>
<item id='ae890ac52d0df67ed7cfdf51b644e901'>
...
</item>
</items>
</event>
<headers xmlns='http://jabber.org/protocol/shim'>
<header name='Collection'>blogs</header>
</headers>
</message>
<message to='bernardo@denmark.lit' from='pubsub.shakespeare.lit'>
<event xmlns='http://jabber.org/protocol/pubsub#event'>
<items node='princely_musings'>
<item id='ae890ac52d0df67ed7cfdf51b644e901'>
...
</item>
</items>
</event>
<headers xmlns='http://jabber.org/protocol/shim'>
<header name='Collection'>blogs</header>
</headers>
</message>
.
.
.
]]></example>
<p>Note: The delivery options (such as "pubsub#deliver_payloads") are determined by the publishing leaf node, not by the aggregating collection node. If the owner of a collection node sets delivery options for a collection node, the service SHOULD ignore those options and apply the options set for the leaf node that publishes an item.</p>
</section2>
</section1>
<section1 topic='IM Account Integration' anchor='presence'> <section1 topic='IM Account Integration' anchor='presence'>
<p>Publish-subscribe functionality can be integrated into existing instant messaging and presence services (see <cite>RFC 3921</cite>), such that each registered account functions as a virtual pubsub service (sometimes called "pubsub-on-a-JID"). In such deployments, the root pubsub node for each virtual pubsub service has the same address as the bare JID &BAREJID; of the account, which is typically associated with an IM user (e.g., &lt;hamlet@denmark.lit&gt;). Since an IM user typically has a roster of "buddies" and shares presence information with those buddies, the virtual pubsub service can use roster and presence information to provide some helpful shortcuts for subscribers, in particular the auto-subscribe and filtered-notifications features described in this section.</p> <p>Publish-subscribe functionality can be integrated into existing instant messaging and presence services (see <cite>RFC 3921</cite>), such that each registered account functions as a virtual pubsub service (sometimes called "pubsub-on-a-JID"). In such deployments, the root pubsub node for each virtual pubsub service has the same address as the bare JID &BAREJID; of the account, which is typically associated with an IM user (e.g., &lt;hamlet@denmark.lit&gt;). Since an IM user typically has a roster of "buddies" and shares presence information with those buddies, the virtual pubsub service can use roster and presence information to provide some helpful shortcuts for subscribers, in particular the auto-subscribe and filtered-notifications features described in this section.</p>
<p>Note: Because the account owner's bare JID functions as a virtual pubsub service, it is OPTIONAL for the owner to include a 'to' address when sending publish requests and completing other publisher and owner use cases. That is, when the IM server receives a pubsub-related IQ stanza of type "get" or "set" from one of the account owner's resources, the server MUST consider the stanza to be addressed to the account owner's bare JID even if the IQ stanza does not include a 'to' address.</p> <p>Note: Because the account owner's bare JID functions as a virtual pubsub service, it is OPTIONAL for the owner to include a 'to' address when sending publish requests and completing other publisher and owner use cases. That is, when the IM server receives a pubsub-related IQ stanza of type "get" or "set" from one of the account owner's resources, the server MUST consider the stanza to be addressed to the account owner's bare JID even if the IQ stanza does not include a 'to' address.</p>
@ -5619,8 +4885,8 @@ And by opposing end them?
<tr> <tr>
<td>collections</td> <td>collections</td>
<td>Collection nodes are supported.</td> <td>Collection nodes are supported.</td>
<td>RECOMMENDED</td> <td>OPTIONAL</td>
<td><link url='#collections'>Collection Nodes</link></td> <td>Refer to <cite>XEP-0248</cite></td>
</tr> </tr>
<tr> <tr>
<td>config-node</td> <td>config-node</td>
@ -5714,9 +4980,9 @@ And by opposing end them?
</tr> </tr>
<tr> <tr>
<td>multi-collection</td> <td>multi-collection</td>
<td>A single leaf node may be associated with multiple collections.</td> <td>A single leaf node can be associated with multiple collections.</td>
<td>OPTIONAL</td> <td>OPTIONAL</td>
<td><link url='#collections-createassociated'>Create a Node Associated with a Collection</link> and <link url='#collections-associate'>Associate an Existing Node with a Collection</link></td> <td>Refer to <cite>XEP-0248</cite></td>
</tr> </tr>
<tr> <tr>
<td>multi-subscribe</td> <td>multi-subscribe</td>
@ -5750,7 +5016,7 @@ And by opposing end them?
</tr> </tr>
<tr> <tr>
<td>publish</td> <td>publish</td>
<td>Publishing items is supported (note: not valid for collection nodes).</td> <td>Publishing items is supported.</td>
<td>REQUIRED</td> <td>REQUIRED</td>
<td><link url='#publisher-publish'>Publish an Item to a Node</link></td> <td><link url='#publisher-publish'>Publish an Item to a Node</link></td>
</tr> </tr>
@ -5983,7 +5249,7 @@ And by opposing end them?
</section2> </section2>
<section2 topic='NodeID Semantics' anchor='impl-semantics'> <section2 topic='NodeID Semantics' anchor='impl-semantics'>
<p>NodeIDs MAY have semantic meaning in particular profiles, implementations, or deployments of pubsub. However, it is STRONGLY RECOMMENDED that such semantic meaning not be used to encapsulate the hierarchical structure of nodes; instead, node hierarchy SHOULD be encapsulated using collections and their associated child nodes.</p> <p>NodeIDs MAY have semantic meaning in particular profiles, implementations, or deployments of pubsub. However, it is STRONGLY RECOMMENDED that such semantic meaning not be used to encapsulate the hierarchical structure of nodes; instead, node hierarchy SHOULD be encapsulated using collections and their associated child nodes as described in <cite>XEP-0248</cite>.</p>
</section2> </section2>
<section2 topic='Multiple Node Discovery' anchor='impl-multiple'> <section2 topic='Multiple Node Discovery' anchor='impl-multiple'>
@ -6021,7 +5287,7 @@ And by opposing end them?
<li>Sending notifications regarding newly-published items as described in the <link url='#publisher-publish'>Publish an Item to a Node</link> use case.</li> <li>Sending notifications regarding newly-published items as described in the <link url='#publisher-publish'>Publish an Item to a Node</link> use case.</li>
<li>Sending notifications regarding deleted items as described in the <link url='#publisher-delete'>Delete an Item from a Node</link> use case.</li> <li>Sending notifications regarding deleted items as described in the <link url='#publisher-delete'>Delete an Item from a Node</link> use case.</li>
</ul> </ul>
<p>The SHIM headers are generated by the node to which the subscriber has a subscription, which may be either a leaf node or a collection node.</p> <p>The SHIM headers are generated by the node to which the subscriber has a subscription, which may be either a leaf node or a collection node (refer to <cite>XEP-0248</cite>).</p>
<p>SHIM headers are not to be included when the content does not differ based on subscription ID, e.g., when a node sends notification of a configuration change to the node itself, notification that the node has been purged, or notification that the node has been deleted.</p> <p>SHIM headers are not to be included when the content does not differ based on subscription ID, e.g., when a node sends notification of a configuration change to the node itself, notification that the node has been purged, or notification that the node has been deleted.</p>
</section2> </section2>
@ -6373,11 +5639,11 @@ O, what a rogue and peasant slave am I!
<table caption='Service Discovery Types in Pubsub Category'> <table caption='Service Discovery Types in Pubsub Category'>
<tr> <tr>
<td>collection</td> <td>collection</td>
<td>A pubsub node of the "collection" type.</td> <td>A pubsub node of the "collection" type as described in XEP-0248.</td>
</tr> </tr>
<tr> <tr>
<td>leaf</td> <td>leaf</td>
<td>A pubsub node of the "leaf" type.</td> <td>A pubsub node of the "leaf" type as described in XEP-0060.</td>
</tr> </tr>
<tr> <tr>
<td>service</td> <td>service</td>
@ -6392,7 +5658,7 @@ O, what a rogue and peasant slave am I!
<type> <type>
<name>collection</name> <name>collection</name>
<desc>A pubsub node of the "collection" type.</desc> <desc>A pubsub node of the "collection" type.</desc>
<doc>XEP-0060</doc> <doc>XEP-0248</doc>
</type> </type>
<type> <type>
<name>leaf</name> <name>leaf</name>
@ -6450,7 +5716,7 @@ O, what a rogue and peasant slave am I!
<var> <var>
<name>http://jabber.org/protocol/pubsub#collections</name> <name>http://jabber.org/protocol/pubsub#collections</name>
<desc>Collection nodes are supported.</desc> <desc>Collection nodes are supported.</desc>
<doc>XEP-0060</doc> <doc>XEP-0248</doc>
</var> </var>
<var> <var>
<name>http://jabber.org/protocol/pubsub#config-node</name> <name>http://jabber.org/protocol/pubsub#config-node</name>
@ -6532,7 +5798,7 @@ O, what a rogue and peasant slave am I!
</var> </var>
<var> <var>
<name>http://jabber.org/protocol/pubsub#multi-collection</name> <name>http://jabber.org/protocol/pubsub#multi-collection</name>
<desc>A single leaf node may be associated with multiple collections.</desc> <desc>A single leaf node can be associated with multiple collections.</desc>
<doc>XEP-0060</doc> <doc>XEP-0060</doc>
</var> </var>
<var> <var>
@ -6975,7 +6241,7 @@ O, what a rogue and peasant slave am I!
<header> <header>
<name>Collection</name> <name>Collection</name>
<desc>The collection via which a notification was received from the originating node.</desc> <desc>The collection via which a notification was received from the originating node.</desc>
<doc>XEP-0060</doc> <doc>XEP-0248</doc>
</header> </header>
<header> <header>
<name>SubID</name> <name>SubID</name>