package org.jivesoftware.openfire.plugin.gojara.messagefilter.processors;
import java.util.Timer;
import java.util.TimerTask;
import org.dom4j.Attribute;
import org.dom4j.Element;
import org.dom4j.QName;
import org.dom4j.tree.DefaultAttribute;
import org.dom4j.tree.DefaultElement;
import org.jivesoftware.openfire.interceptor.InterceptorManager;
import org.jivesoftware.openfire.interceptor.PacketInterceptor;
import org.jivesoftware.openfire.interceptor.PacketRejectedException;
import org.jivesoftware.openfire.session.Session;
import org.jivesoftware.util.JiveGlobals;
import org.xmpp.packet.IQ;
import org.xmpp.packet.Packet;
/**
* This implements a special IQ package for Spark client. Spark checks the
* disco#info package send from external component for a <registered> tag.
* Because spectrum does not support this feature we have to modify the disco
* package from spectrum with the registered tag if the user is registered with
* this gateway. Part of command pattern used in {@link MainInterceptor}
*
* @author Holger Bergunde
*
*/
public class DiscoIQRegisteredProcessor extends AbstractRemoteRosterProcessor {
private boolean _isRegistered = false;
public DiscoIQRegisteredProcessor() {
Log.info("Created DiscoIQRegisteredProcessor");
}
@Override
public void process(Packet packet, final String subdomain, String to, String from) throws PacketRejectedException {
Log.debug("Processing packet in DiscoIQRegisteredProcessor for " + subdomain);
// Check if the jabber:iq:register is enabled in admin panel
boolean isFeatureEnabled = JiveGlobals.getBooleanProperty("plugin.remoteroster.sparkDiscoInfo", false);
if (!isFeatureEnabled) {
Log.debug("Spark extension is deactivated. Won't change the disco#info");
return;
}
final InterceptorManager interceptorManager = InterceptorManager.getInstance();
final PacketInterceptor interceptor = new PacketInterceptor() {
public void interceptPacket(Packet packet, Session session, boolean incoming, boolean processed) throws PacketRejectedException {
if (!processed && incoming) {
if (packet instanceof IQ) {
IQ iqPacket = (IQ) packet;
Element packetElement = iqPacket.getChildElement();
if (packetElement == null)
return;
String ns = iqPacket.getChildElement().getNamespace().getURI();
if (iqPacket.getType().equals(IQ.Type.result) && ns.equals("jabber:iq:register")
&& iqPacket.getFrom().toString().equals(subdomain)) {
// Check if we are already registered
setRegistered(iqPacket.toString().contains("<registered/>"));
throw new PacketRejectedException();
} else if (iqPacket.getType().equals(IQ.Type.result) && ns.equals("http://jabber.org/protocol/disco#info")
&& iqPacket.getFrom().toString().equals(subdomain)) {
/*
* This is the answer of the disco#info from spark
* to our component. add the jabber:iq:register
* feature if we are registered
*/
if (isRegistered()) {
Log.debug("Modifying disco#info packge to send registered iq feature to Spark user "
+ iqPacket.getTo().toString());
Attribute attribut = new DefaultAttribute("var", "jabber:iq:registered");
iqPacket.getChildElement().addElement("feature").add(attribut);
}
}
}
}
}
};
Log.debug("Creating my own listener for jabber:iq:register result to external component " + subdomain);
interceptorManager.addInterceptor(interceptor);
IQ askComponent = new IQ();
askComponent.setTo(to);
askComponent.setFrom(from);
askComponent.setType(IQ.Type.get);
Element query = new DefaultElement( QName.get( "query", "jabber:iq:register" ) );
askComponent.setChildElement(query);
// Remove the package intercepter in 1sec
TimerTask removeInterceptorTask = new TimerTask() {
@Override
public void run() {
Log.debug("Removing my created listener for jabber:iq:register. Component " + subdomain);
interceptorManager.removeInterceptor(interceptor);
}
};
Timer timer = new Timer();
timer.schedule(removeInterceptorTask, 1000);
// Send the register query to component
dispatchPacket(askComponent);
}
private boolean isRegistered() {
return _isRegistered;
}
private void setRegistered(boolean bool) {
_isRegistered = bool;
}
}