return;
}
// 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(subscriberJID.toBareJID());
// Check if the node's access model allows the subscription to proceed
AccessModel accessModel = node.getAccessModel();
if (!accessModel.canSubscribe(node, owner, subscriberJID)) {
sendErrorPacket(iq, accessModel.getSubsriptionError(),
accessModel.getSubsriptionErrorDetail());
return;
}
// Check if the subscriber is an anonymous user
if (!UserManager.getInstance().isRegisteredUser(subscriberJID)) {
// Anonymous users cannot subscribe to the node. Return forbidden error
sendErrorPacket(iq, PacketError.Condition.forbidden, null);
return;
}
// Check if the subscription owner is a user with outcast affiliation
NodeAffiliate nodeAffiliate = node.getAffiliate(owner);
if (nodeAffiliate != null &&
nodeAffiliate.getAffiliation() == NodeAffiliate.Affiliation.outcast) {
// Subscriber is an outcast. Return forbidden error
sendErrorPacket(iq, PacketError.Condition.forbidden, null);
return;
}
// Check that subscriptions to the node are enabled
if (!node.isSubscriptionEnabled() && !service.isServiceAdmin(from)) {
// Sender is not a sysadmin and subscription is disabled so return an error
sendErrorPacket(iq, PacketError.Condition.not_allowed, null);
return;
}
// Get any configuration form included in the options element (if any)
DataForm optionsForm = null;
Element options = childElement.element("options");
if (options != null) {
Element formElement = options.element(QName.get("x", "jabber:x:data"));
if (formElement != null) {
optionsForm = new DataForm(formElement);
}
}
// If leaf node does not support multiple subscriptions then check whether subscriber is
// creating another subscription or not
if (!node.isCollectionNode() && !node.isMultipleSubscriptionsEnabled()) {
NodeSubscription existingSubscription = node.getSubscription(subscriberJID);
if (existingSubscription != null) {
// User is trying to create another subscription so
// return current subscription state
existingSubscription.sendSubscriptionState(iq);
return;
}
}
// Check if subscribing twice to a collection node using same subscription type
if (node.isCollectionNode()) {
// By default assume that new subscription is of type node
boolean isNodeType = true;
if (optionsForm != null) {
FormField field = optionsForm.getField("pubsub#subscription_type");
if (field != null) {
if ("items".equals(field.getValues().get(0))) {
isNodeType = false;
}
}
}
if (nodeAffiliate != null) {
for (NodeSubscription subscription : nodeAffiliate.getSubscriptions()) {
if (isNodeType) {
// User is requesting a subscription of type "nodes"
if (NodeSubscription.Type.nodes == subscription.getType()) {
// Cannot have 2 subscriptions of the same type. Return conflict error
sendErrorPacket(iq, PacketError.Condition.conflict, null);
return;
}
}
else if (!node.isMultipleSubscriptionsEnabled()) {
// User is requesting a subscription of type "items" and
// multiple subscriptions is not allowed
if (NodeSubscription.Type.items == subscription.getType()) {
// User is trying to create another subscription so
// return current subscription state
subscription.sendSubscriptionState(iq);
return;
}
}
}
}
}
// Create a subscription and an affiliation if the subscriber doesn't have one
node.createSubscription(iq, owner, subscriberJID, accessModel.isAuthorizationRequired(),
optionsForm);
}