Commit fd99960a authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Update implementation based on...

Update implementation based on http://www.jabber.org/jeps/tmp/jep-0060-1.8.html#owner-subscriptions and http://www.jabber.org/jeps/tmp/jep-0060-1.8.html#owner-affiliations. JM-672

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk@3839 b35dd754-fafc-0310-a699-88a17e54d16e
parent 9d379819
...@@ -1861,29 +1861,45 @@ public abstract class Node { ...@@ -1861,29 +1861,45 @@ public abstract class Node {
} }
/** /**
* Sends the list of affiliated entities with the node to the owner that sent the IQ * Sends the list of affiliations with the node to the owner that sent the IQ
* request. * request.
* *
* @param iqRequest IQ request sent by an owner of the node. * @param iqRequest IQ request sent by an owner of the node.
*/ */
void sendAffiliatedEntities(IQ iqRequest) { void sendAffiliations(IQ iqRequest) {
IQ reply = IQ.createResultIQ(iqRequest); IQ reply = IQ.createResultIQ(iqRequest);
Element childElement = iqRequest.getChildElement().createCopy(); Element childElement = iqRequest.getChildElement().createCopy();
reply.setChildElement(childElement); reply.setChildElement(childElement);
for (NodeAffiliate affiliate : affiliates) { for (NodeAffiliate affiliate : affiliates) {
Collection<NodeSubscription> subscriptions = affiliate.getSubscriptions(); if (affiliate.getAffiliation() == NodeAffiliate.Affiliation.none) {
if (subscriptions.isEmpty()) { continue;
Element entity = childElement.addElement("entity"); }
Element entity = childElement.addElement("affiliation");
entity.addAttribute("jid", affiliate.getJID().toString()); entity.addAttribute("jid", affiliate.getJID().toString());
entity.addAttribute("affiliation", affiliate.getAffiliation().name()); entity.addAttribute("affiliation", affiliate.getAffiliation().name());
entity.addAttribute("subscription", "none");
} }
else { }
for (NodeSubscription subscription : subscriptions) {
Element entity = childElement.addElement("entity"); /**
* Sends the list of subscriptions with the node to the owner that sent the IQ
* request.
*
* @param iqRequest IQ request sent by an owner of the node.
*/
void sendSubscriptions(IQ iqRequest) {
IQ reply = IQ.createResultIQ(iqRequest);
Element childElement = iqRequest.getChildElement().createCopy();
reply.setChildElement(childElement);
for (NodeAffiliate affiliate : affiliates) {
for (NodeSubscription subscription : affiliate.getSubscriptions()) {
if (subscription.isAuthorizationPending()) {
continue;
}
Element entity = childElement.addElement("subscription");
entity.addAttribute("jid", subscription.getJID().toString()); entity.addAttribute("jid", subscription.getJID().toString());
entity.addAttribute("affiliation", affiliate.getAffiliation().name()); //entity.addAttribute("affiliation", affiliate.getAffiliation().name());
entity.addAttribute("subscription", subscription.getState().name()); entity.addAttribute("subscription", subscription.getState().name());
if (isMultipleSubscriptionsEnabled()) { if (isMultipleSubscriptionsEnabled()) {
entity.addAttribute("subid", subscription.getID()); entity.addAttribute("subid", subscription.getID());
...@@ -1891,7 +1907,6 @@ public abstract class Node { ...@@ -1891,7 +1907,6 @@ public abstract class Node {
} }
} }
} }
}
/** /**
* Broadcasts a node event to subscribers of the node. * Broadcasts a node event to subscribers of the node.
......
...@@ -221,14 +221,25 @@ public class PubSubEngine { ...@@ -221,14 +221,25 @@ public class PubSubEngine {
deleteNode(iq, action); deleteNode(iq, action);
return true; return true;
} }
action = childElement.element("entities"); action = childElement.element("subscriptions");
if (action != null) { if (action != null) {
if (IQ.Type.get == iq.getType()) { if (IQ.Type.get == iq.getType()) {
// Owner requests all affiliated entities // Owner requests all affiliated entities
getAffiliatedEntities(iq, action); getNodeSubscriptions(iq, action);
} }
else { else {
modifyAffiliations(iq, action); modifyNodeSubscriptions(iq, action);
}
return true;
}
action = childElement.element("affiliations");
if (action != null) {
if (IQ.Type.get == iq.getType()) {
// Owner requests all affiliated entities
getNodeAffiliations(iq, action);
}
else {
modifyNodeAffiliations(iq, action);
} }
return true; return true;
} }
...@@ -1397,8 +1408,8 @@ public class PubSubEngine { ...@@ -1397,8 +1408,8 @@ public class PubSubEngine {
router.route(IQ.createResultIQ(iq)); router.route(IQ.createResultIQ(iq));
} }
private void getAffiliatedEntities(IQ iq, Element affiliatedElement) { private void getNodeSubscriptions(IQ iq, Element affiliationsElement) {
String nodeID = affiliatedElement.attributeValue("node"); String nodeID = affiliationsElement.attributeValue("node");
if (nodeID == null) { if (nodeID == null) {
// NodeID was not provided. Return bad-request error. // NodeID was not provided. Return bad-request error.
sendErrorPacket(iq, PacketError.Condition.bad_request, null); sendErrorPacket(iq, PacketError.Condition.bad_request, null);
...@@ -1416,11 +1427,11 @@ public class PubSubEngine { ...@@ -1416,11 +1427,11 @@ public class PubSubEngine {
return; return;
} }
// Ask the node to send the list of affiliated entities to the owner // Ask the node to send the list of subscriptions to the owner
node.sendAffiliatedEntities(iq); node.sendSubscriptions(iq);
} }
private void modifyAffiliations(IQ iq, Element entitiesElement) { private void modifyNodeSubscriptions(IQ iq, Element entitiesElement) {
String nodeID = entitiesElement.attributeValue("node"); String nodeID = entitiesElement.attributeValue("node");
if (nodeID == null) { if (nodeID == null) {
// NodeID was not provided. Return bad-request error. // NodeID was not provided. Return bad-request error.
...@@ -1440,18 +1451,96 @@ public class PubSubEngine { ...@@ -1440,18 +1451,96 @@ public class PubSubEngine {
} }
IQ reply = IQ.createResultIQ(iq); IQ reply = IQ.createResultIQ(iq);
Collection<JID> invalidAffiliates = new ArrayList<JID>();
// Process modifications or creations of affiliations and subscriptions. // Process modifications or creations of affiliations and subscriptions.
for (Iterator it = entitiesElement.elementIterator("entity"); it.hasNext();) { for (Iterator it = entitiesElement.elementIterator("subscription"); it.hasNext();) {
Element entity = (Element) it.next(); Element entity = (Element) it.next();
JID subscriber = new JID(entity.attributeValue("jid")); JID subscriber = new JID(entity.attributeValue("jid"));
// TODO Assumed that the owner of the subscription is the bare JID of the subscription JID. Waiting StPeter answer for explicit field. // TODO Assumed that the owner of the subscription is the bare JID of the subscription JID. Waiting StPeter answer for explicit field.
JID owner = new JID(subscriber.toBareJID()); JID owner = new JID(subscriber.toBareJID());
String newAffiliation = entity.attributeValue("affiliation");
String subStatus = entity.attributeValue("subscription"); String subStatus = entity.attributeValue("subscription");
String subID = entity.attributeValue("subid"); String subID = entity.attributeValue("subid");
if (newAffiliation != null) { // Process subscriptions changes
// Get current subscription (if any)
NodeSubscription subscription = null;
if (node.isMultipleSubscriptionsEnabled()) {
if (subID != null) {
subscription = node.getSubscription(subID);
}
}
else {
subscription = node.getSubscription(subscriber);
}
if ("none".equals(subStatus) && subscription != null) {
// Owner is cancelling an existing subscription
node.cancelSubscription(subscription);
}
else if ("subscribed".equals(subStatus)) {
if (subscription != null) {
// Owner is approving a subscription (i.e. making active)
node.approveSubscription(subscription, true);
}
else {
// Owner is creating a subscription for an entity to the node
node.createSubscription(null, owner, subscriber, false, null);
}
}
}
// Send reply
router.route(reply);
}
private void getNodeAffiliations(IQ iq, Element affiliationsElement) {
String nodeID = affiliationsElement.attributeValue("node");
if (nodeID == null) {
// NodeID was not provided. Return bad-request error.
sendErrorPacket(iq, PacketError.Condition.bad_request, null);
return;
}
Node node = service.getNode(nodeID);
if (node == null) {
// Node does not exist. Return item-not-found error.
sendErrorPacket(iq, PacketError.Condition.item_not_found, null);
return;
}
if (!node.isAdmin(iq.getFrom())) {
// Requesting entity is prohibited from getting affiliates list. Return forbidden error.
sendErrorPacket(iq, PacketError.Condition.forbidden, null);
return;
}
// Ask the node to send the list of affiliations to the owner
node.sendAffiliations(iq);
}
private void modifyNodeAffiliations(IQ iq, Element entitiesElement) {
String nodeID = entitiesElement.attributeValue("node");
if (nodeID == null) {
// NodeID was not provided. Return bad-request error.
sendErrorPacket(iq, PacketError.Condition.bad_request, null);
return;
}
Node node = service.getNode(nodeID);
if (node == null) {
// Node does not exist. Return item-not-found error.
sendErrorPacket(iq, PacketError.Condition.item_not_found, null);
return;
}
if (!node.isAdmin(iq.getFrom())) {
// Requesting entity is prohibited from getting affiliates list. Return forbidden error.
sendErrorPacket(iq, PacketError.Condition.forbidden, null);
return;
}
IQ reply = IQ.createResultIQ(iq);
Collection<JID> invalidAffiliates = new ArrayList<JID>();
// Process modifications or creations of affiliations
for (Iterator it = entitiesElement.elementIterator("affiliation"); it.hasNext();) {
Element affiliation = (Element) it.next();
JID owner = new JID(affiliation.attributeValue("jid"));
String newAffiliation = affiliation.attributeValue("affiliation");
// Get current affiliation of this user (if any) // Get current affiliation of this user (if any)
NodeAffiliate affiliate = node.getAffiliate(owner); NodeAffiliate affiliate = node.getAffiliate(owner);
...@@ -1481,34 +1570,6 @@ public class PubSubEngine { ...@@ -1481,34 +1570,6 @@ public class PubSubEngine {
node.addOutcast(owner); node.addOutcast(owner);
} }
} }
// Process subscriptions changes
if (subStatus != null) {
// Get current subscription (if any)
NodeSubscription subscription = null;
if (node.isMultipleSubscriptionsEnabled()) {
if (subID != null) {
subscription = node.getSubscription(subID);
}
}
else {
subscription = node.getSubscription(subscriber);
}
if ("none".equals(subStatus) && subscription != null) {
// Owner is cancelling an existing subscription
node.cancelSubscription(subscription);
}
else if ("subscribed".equals(subStatus)) {
if (subscription != null) {
// Owner is approving a subscription (i.e. making active)
node.approveSubscription(subscription, true);
}
else {
// Owner is creating a subscription for an entity to the node
node.createSubscription(null, owner, subscriber, false, null);
}
}
}
}
// Process invalid entities that tried to remove node owners. Send original affiliation // Process invalid entities that tried to remove node owners. Send original affiliation
// of the invalid entities. // of the invalid entities.
...@@ -1516,30 +1577,15 @@ public class PubSubEngine { ...@@ -1516,30 +1577,15 @@ public class PubSubEngine {
reply.setError(PacketError.Condition.not_acceptable); reply.setError(PacketError.Condition.not_acceptable);
Element child = Element child =
reply.setChildElement("pubsub", "http://jabber.org/protocol/pubsub#owner"); reply.setChildElement("pubsub", "http://jabber.org/protocol/pubsub#owner");
Element entities = child.addElement("entities"); Element entities = child.addElement("affiliations");
if (!node.isRootCollectionNode()) { if (!node.isRootCollectionNode()) {
entities.addAttribute("node", node.getNodeID()); entities.addAttribute("node", node.getNodeID());
} }
for (JID affiliateJID : invalidAffiliates) { for (JID affiliateJID : invalidAffiliates) {
NodeAffiliate affiliate = node.getAffiliate(affiliateJID); NodeAffiliate affiliate = node.getAffiliate(affiliateJID);
Collection<NodeSubscription> subscriptions = affiliate.getSubscriptions(); Element entity = entities.addElement("affiliation");
if (subscriptions.isEmpty()) {
Element entity = entities.addElement("entity");
entity.addAttribute("jid", affiliate.getJID().toString()); entity.addAttribute("jid", affiliate.getJID().toString());
entity.addAttribute("affiliation", affiliate.getAffiliation().name()); entity.addAttribute("affiliation", affiliate.getAffiliation().name());
entity.addAttribute("subscription", "none");
}
else {
for (NodeSubscription subscription : subscriptions) {
Element entity = entities.addElement("entity");
entity.addAttribute("jid", subscription.getJID().toString());
entity.addAttribute("affiliation", affiliate.getAffiliation().name());
entity.addAttribute("subscription", subscription.getState().name());
if (node.isMultipleSubscriptionsEnabled()) {
entity.addAttribute("subid", subscription.getID());
}
}
}
} }
} }
// Send reply // Send reply
......
...@@ -512,6 +512,8 @@ public class PubSubModule extends BasicModule implements ServerItemsProvider, Di ...@@ -512,6 +512,8 @@ public class PubSubModule extends BasicModule implements ServerItemsProvider, Di
features.add("http://jabber.org/protocol/pubsub#meta-data"); features.add("http://jabber.org/protocol/pubsub#meta-data");
// Node owners may modify affiliations // Node owners may modify affiliations
features.add("http://jabber.org/protocol/pubsub#modify-affiliations"); features.add("http://jabber.org/protocol/pubsub#modify-affiliations");
// Node owners may manage subscriptions.
features.add("http://jabber.org/protocol/pubsub#manage-subscriptions");
// A single entity may subscribe to a node multiple times // A single entity may subscribe to a node multiple times
features.add("http://jabber.org/protocol/pubsub#multi-subscribe"); features.add("http://jabber.org/protocol/pubsub#multi-subscribe");
// The outcast affiliation is supported // The outcast affiliation is supported
...@@ -530,8 +532,12 @@ public class PubSubModule extends BasicModule implements ServerItemsProvider, Di ...@@ -530,8 +532,12 @@ public class PubSubModule extends BasicModule implements ServerItemsProvider, Di
features.add("http://jabber.org/protocol/pubsub#retract-items"); features.add("http://jabber.org/protocol/pubsub#retract-items");
// Retrieval of current affiliations is supported // Retrieval of current affiliations is supported
features.add("http://jabber.org/protocol/pubsub#retrieve-affiliations"); features.add("http://jabber.org/protocol/pubsub#retrieve-affiliations");
// Retrieval of default node configuration is supported.
features.add("http://jabber.org/protocol/pubsub#retrieve-default");
// Item retrieval is supported // Item retrieval is supported
features.add("http://jabber.org/protocol/pubsub#retrieve-items"); features.add("http://jabber.org/protocol/pubsub#retrieve-items");
// Retrieval of current subscriptions is supported.
features.add("http://jabber.org/protocol/pubsub#retrieve-subscriptions");
// Subscribing and unsubscribing are supported // Subscribing and unsubscribing are supported
features.add("http://jabber.org/protocol/pubsub#subscribe"); features.add("http://jabber.org/protocol/pubsub#subscribe");
// Configuration of subscription options is supported // Configuration of subscription options is supported
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment