package org.buddycloud.channelserver.packetprocessor.iq.namespace.pubsub.result;
import java.util.Date;
import java.util.List;
import org.apache.log4j.Logger;
import org.buddycloud.channelserver.Configuration;
import org.buddycloud.channelserver.channel.ChannelManager;
import org.buddycloud.channelserver.channel.Conf;
import org.buddycloud.channelserver.db.exception.NodeStoreException;
import org.buddycloud.channelserver.packetprocessor.iq.namespace.pubsub.PubSubElementProcessorAbstract;
import org.buddycloud.channelserver.pubsub.affiliation.Affiliations;
import org.buddycloud.channelserver.pubsub.model.NodeSubscription;
import org.buddycloud.channelserver.pubsub.model.impl.GlobalItemIDImpl;
import org.buddycloud.channelserver.pubsub.model.impl.NodeItemImpl;
import org.buddycloud.channelserver.pubsub.model.impl.NodeSubscriptionImpl;
import org.buddycloud.channelserver.pubsub.subscription.Subscriptions;
import org.buddycloud.channelserver.utils.XMLConstants;
import org.dom4j.Element;
import org.xmpp.packet.IQ;
import org.xmpp.packet.JID;
public class ItemsResult extends PubSubElementProcessorAbstract {
private static final String MISSING_NODE = "Missing node";
private static final Logger LOGGER = Logger.getLogger(ItemsResult.class);
private boolean subscriptionNode = false;
public ItemsResult(ChannelManager channelManager) {
this.channelManager = channelManager;
this.acceptedElementName = XMLConstants.ITEMS_ELEM;
}
public void process(Element elm, JID actorJID, IQ reqIQ, Element rsm) throws Exception {
this.request = reqIQ;
if (-1 != request.getFrom().toString().indexOf("@")) {
LOGGER.debug("Ignoring result packet, only interested in stanzas " + "from other buddycloud servers");
return;
}
if (null != elm.attributeValue(XMLConstants.NODE_ATTR)) {
this.setNode(elm.attributeValue(XMLConstants.NODE_ATTR));
}
if ((null == node) || "".equals(node)) {
throw new NullPointerException(MISSING_NODE);
}
subscriptionNode = (node.substring(node.length() - 13, node.length()).equals(XMLConstants.SUBSCRIPTIONS_ELEM));
if ((!subscriptionNode) && (!channelManager.nodeExists(node))) {
channelManager.addRemoteNode(node);
}
@SuppressWarnings("unchecked")
List<Element> items = request.getElement().element(XMLConstants.PUBSUB_ELEM).element(XMLConstants.ITEMS_ELEM).elements(XMLConstants.ITEM_ELEM);
for (Element item : items) {
if (subscriptionNode) {
processSubscriptionItem(item);
} else {
processPublishedItem(item);
}
}
}
@SuppressWarnings("unchecked")
private void processSubscriptionItem(Element item) throws NodeStoreException {
JID user = new JID(item.attributeValue(XMLConstants.ID_ATTR));
List<Element> items = item.element("query").elements(XMLConstants.ITEM_ELEM);
for (Element subscription : items) {
try {
addSubscription(subscription, user);
} catch (IllegalArgumentException e) {
LOGGER.error(e);
}
}
}
private void addSubscription(Element item, JID user) throws NodeStoreException {
String node = item.attributeValue(XMLConstants.NODE_ATTR);
// If its a local JID and/or a local node, that's our turf!
if ((Configuration.getInstance().isLocalNode(node)) && (Configuration.getInstance().isLocalJID(user))) {
return;
}
if (Configuration.getInstance().isLocalNode(node)) {
return;
}
JID listener = request.getFrom();
Subscriptions sub = Subscriptions.createFromString(item.attributeValue(XMLConstants.SUBSCRIPTION_ELEM));
Affiliations aff = Affiliations.createFromString(item.attributeValue(XMLConstants.AFFILIATION_ELEM));
NodeSubscription subscription = new NodeSubscriptionImpl(node, user, listener, sub, null);
if (false == channelManager.nodeExists(node)) {
channelManager.addRemoteNode(node);
}
channelManager.addUserSubscription(subscription);
channelManager.setUserAffiliation(node, user, aff);
}
private void processPublishedItem(Element item) throws NodeStoreException {
Element entry = item.element("entry");
try {
// Probably a tombstone'd item
if (null == entry.elementText("updated")) {
LOGGER.debug("Entry has no 'updated' element, won't process");
return;
}
String inReplyTo = null;
Element reply;
if (null != (reply = entry.element("in-reply-to"))) {
String[] inReplyToParts = reply.attributeValue("ref").split(",");
inReplyTo = inReplyToParts[inReplyToParts.length - 1];
}
Date updatedDate = Conf.parseDate(entry.elementText("updated"));
NodeItemImpl nodeItem = new NodeItemImpl(node, GlobalItemIDImpl.toLocalId(entry.elementText("id")), updatedDate, entry.asXML(), inReplyTo);
try {
channelManager.deleteNodeItemById(node, entry.elementText("id"));
} catch (NodeStoreException e) {
LOGGER.error("Attempt to delete an item which didn't exist... its ok");
}
channelManager.addNodeItem(nodeItem);
} catch (IllegalArgumentException e) {
LOGGER.error(e);
e.printStackTrace();
return;
}
}
}