package org.jivesoftware.openfire.plugin.gojara.base; import java.io.File; import java.util.HashSet; import java.util.List; import java.util.Set; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.Node; import org.jivesoftware.openfire.component.ComponentEventListener; import org.jivesoftware.openfire.component.InternalComponentManager; import org.jivesoftware.openfire.container.Plugin; import org.jivesoftware.openfire.container.PluginManager; import org.jivesoftware.openfire.interceptor.InterceptorManager; import org.jivesoftware.openfire.plugin.gojara.messagefilter.MainInterceptor; import org.jivesoftware.openfire.plugin.gojara.sessions.GojaraAdminManager; import org.jivesoftware.openfire.plugin.gojara.sessions.TransportSessionManager; import org.jivesoftware.openfire.plugin.gojara.utils.XpathHelper; import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.PropertyEventDispatcher; import org.jivesoftware.util.PropertyEventListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xmpp.packet.IQ; import org.xmpp.packet.JID; /** * @author Holger Bergunde * @author axel.frederik.brand * * This class is the basic reprasentation for the GoJara plugin. It is * the entry point for openfire to start or stop this plugin. * * GoJara has been developed to support XEP-xxx Remote Roster * Management. Further information: <a * href="http://jkaluza.fedorapeople.org/remote-roster.html">Here</a> * * RemoteRoster enables Spectrum IM support for Openfire. Currently only * 2.3, 2.4 and 2.5 implemented. 2.1 and 2.2 of the protocol standard is * not supported by Spectrum IM */ public class RemoteRosterPlugin implements Plugin { private static final Logger Log = LoggerFactory.getLogger(RemoteRosterPlugin.class); private static PluginManager pluginManager; private Set<String> _waitingForIQResponse = new HashSet<String>(); private PropertyEventListener _settingsObserver; private ComponentEventListener _componentObserver; private MainInterceptor mainInterceptor = new MainInterceptor(); private InterceptorManager iManager = InterceptorManager.getInstance(); private InternalComponentManager compManager = InternalComponentManager.getInstance(); private TransportSessionManager transportSessionManager = TransportSessionManager.getInstance(); private GojaraAdminManager gojaraAdminManager = GojaraAdminManager.getInstance(); public void initializePlugin(PluginManager manager, File pluginDirectory) { pluginManager = manager; iManager.addInterceptor(mainInterceptor); manageExternalComponents(); listenToSettings(); transportSessionManager.initializeSessions(); gojaraAdminManager.gatherGatewayStatistics(); Log.info("Started Gojara successfully. Currently running interceptors: "+iManager.getInterceptors().size()); } /** * Handles external components that connect to openfire. We check if the * external component is maybe a gateway and interesting for us */ private void manageExternalComponents() { _componentObserver = new ComponentEventListener() { /* * Check if the unregistered component contains to one of our * package interceptors */ public void componentUnregistered(JID componentJID) { mainInterceptor.removeTransport(componentJID.toString()); } /* * If there is a new external Component, check if it is a gateway * and add create a package interceptor if it is enabled */ public void componentRegistered(JID componentJID) { _waitingForIQResponse.add(componentJID.getDomain()); } public void componentInfoReceived(IQ iq) { String from = iq.getFrom().getDomain(); // Waiting for this external component sending an IQ response to // us? if (_waitingForIQResponse.contains(from)) { Element packet = iq.getChildElement(); Document doc = packet.getDocument(); List<Node> nodes = XpathHelper.findNodesInDocument(doc, "//disco:identity[@category='gateway']"); if (nodes.size() > 0) { updateInterceptors(from); } // We got the IQ, we can now remove it from the set, because // we are not waiting any more _waitingForIQResponse.remove(from); } } }; compManager.addListener(_componentObserver); } /** * Registers a listener for JiveGlobals. We might restart our service, if * there were some changes for our gateways */ private void listenToSettings() { _settingsObserver = new RemoteRosterPropertyListener() { @Override protected void changedProperty(String prop) { updateInterceptors(prop); } }; PropertyEventDispatcher.addListener(_settingsObserver); } public void destroyPlugin() { mainInterceptor.freeze(); iManager.removeInterceptor(mainInterceptor); PropertyEventDispatcher.removeListener(_settingsObserver); compManager.removeListener(_componentObserver); pluginManager = null; mainInterceptor = null; compManager = null; } private void updateInterceptors(String componentJID) { boolean allowed = JiveGlobals.getBooleanProperty("plugin.remoteroster.jids." + componentJID, false); if (allowed) { mainInterceptor.addTransport(componentJID); } else { mainInterceptor.removeTransport(componentJID); } } public String getName() { return "gojara"; } public static PluginManager getPluginManager() { return pluginManager; } }