Commit 31b70147 authored by Holger Bergunde's avatar Holger Bergunde Committed by holger.bergunde

OF-490 implemented 2.4 Client sends roster update by (Proto XEP)

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@12900 b35dd754-fafc-0310-a699-88a17e54d16e
parent dcad8ede
package org.jivesoftware.openfire.plugin; package org.jivesoftware.openfire.plugin;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Node;
import org.dom4j.XPath;
import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.interceptor.PacketInterceptor; import org.jivesoftware.openfire.interceptor.PacketInterceptor;
import org.jivesoftware.openfire.interceptor.PacketRejectedException; import org.jivesoftware.openfire.interceptor.PacketRejectedException;
import org.jivesoftware.openfire.plugin.packageProcessor.AbstractRemoteRosterProcessor; import org.jivesoftware.openfire.plugin.packageProcessor.AbstractRemoteRosterProcessor;
import org.jivesoftware.openfire.plugin.packageProcessor.CleanUpRosterProcessor;
import org.jivesoftware.openfire.plugin.packageProcessor.ClientToComponentUpdateProcessor;
import org.jivesoftware.openfire.plugin.packageProcessor.DiscoIQResigteredProcessor; import org.jivesoftware.openfire.plugin.packageProcessor.DiscoIQResigteredProcessor;
import org.jivesoftware.openfire.plugin.packageProcessor.ReceiveComponentUpdatesProcessor; import org.jivesoftware.openfire.plugin.packageProcessor.ReceiveComponentUpdatesProcessor;
import org.jivesoftware.openfire.plugin.packageProcessor.SendRosterProcessor; import org.jivesoftware.openfire.plugin.packageProcessor.SendRosterProcessor;
...@@ -36,9 +33,13 @@ public class RemotePackageInterceptor implements PacketInterceptor { ...@@ -36,9 +33,13 @@ public class RemotePackageInterceptor implements PacketInterceptor {
AbstractRemoteRosterProcessor sendroster = new SendRosterProcessor(rosterMananger, _mySubdomain); AbstractRemoteRosterProcessor sendroster = new SendRosterProcessor(rosterMananger, _mySubdomain);
AbstractRemoteRosterProcessor receiveChanges = new ReceiveComponentUpdatesProcessor(rosterMananger); AbstractRemoteRosterProcessor receiveChanges = new ReceiveComponentUpdatesProcessor(rosterMananger);
AbstractRemoteRosterProcessor iqRegistered = new DiscoIQResigteredProcessor(_mySubdomain); AbstractRemoteRosterProcessor iqRegistered = new DiscoIQResigteredProcessor(_mySubdomain);
AbstractRemoteRosterProcessor cleanUp = new CleanUpRosterProcessor(rosterMananger, _mySubdomain);
AbstractRemoteRosterProcessor updateToComponent = new ClientToComponentUpdateProcessor(_mySubdomain);
_packetProcessor.put("sendRoster", sendroster); _packetProcessor.put("sendRoster", sendroster);
_packetProcessor.put("receiveChanges", receiveChanges); _packetProcessor.put("receiveChanges", receiveChanges);
_packetProcessor.put("sparkIQRegistered", iqRegistered); _packetProcessor.put("sparkIQRegistered", iqRegistered);
_packetProcessor.put("handleCleanUp", cleanUp);
_packetProcessor.put("clientToComponentUpdate", updateToComponent);
} }
@Override @Override
...@@ -49,57 +50,53 @@ public class RemotePackageInterceptor implements PacketInterceptor { ...@@ -49,57 +50,53 @@ public class RemotePackageInterceptor implements PacketInterceptor {
if (packet instanceof IQ) { if (packet instanceof IQ) {
IQ myPacket = (IQ) packet; IQ myPacket = (IQ) packet;
if (myPacket.getFrom() == null || myPacket.getTo() == null) { if (myPacket.getFrom() == null || myPacket.getTo() == null) {
/*
* If getTo() == null this is maybe a roster update from the
* Client to the Server, check if we should mirror this
* package to external component
*/
if (myPacket.getFrom() != null && myPacket.getType().equals(IQ.Type.set)
&& myPacket.getTo() == null) {
if (Utils.findNodesInDocument(myPacket.getChildElement().getDocument(), "//roster:item").size() > 0) {
_packetProcessor.get("clientToComponentUpdate").process(myPacket);
}
}
return; return;
} }
String to = myPacket.getTo().toString(); String to = myPacket.getTo().toString();
String from = myPacket.getFrom().toString(); String from = myPacket.getFrom().toString();
if (myPacket.getType().equals(IQ.Type.get) && from.equals(_mySubdomain)) { if (myPacket.getType().equals(IQ.Type.get) && from.equals(_mySubdomain)) {
if (findNodesInDocument(myPacket.getElement().getDocument(), "//roster:*").size() == 1) { if (Utils.findNodesInDocument(myPacket.getElement().getDocument(), "//roster:*").size() == 1) {
// This Package is a roster request by remote component // This Package is a roster request by remote component
_packetProcessor.get("sendRoster").process(packet); _packetProcessor.get("sendRoster").process(packet);
} }
} else if (myPacket.getType().equals(IQ.Type.set) && from.equals(_mySubdomain)) { } else if (myPacket.getType().equals(IQ.Type.set) && from.equals(_mySubdomain)) {
if (findNodesInDocument(myPacket.getElement().getDocument(), "//roster:item").size() >= 1) { if (Utils.findNodesInDocument(myPacket.getElement().getDocument(), "//roster:item").size() >= 1) {
// Component sends roster update // Component sends roster update
_packetProcessor.get("receiveChanges").process(packet); _packetProcessor.get("receiveChanges").process(packet);
} }
} else if (myPacket.getType().equals(IQ.Type.get) } else if (myPacket.getType().equals(IQ.Type.get)
&& myPacket.toString().contains("http://jabber.org/protocol/disco#info") && myPacket.toString().contains("http://jabber.org/protocol/disco#info")
&& myPacket.getTo().toString().equals(_mySubdomain)) { && myPacket.getTo().toString().equals(_mySubdomain)) {
//modify the disco#info for spark clients if enabled in admin panel /*
* modify the disco#info for spark clients if enabled in
* admin panel
*/
_packetProcessor.get("sparkIQRegistered").process(packet); _packetProcessor.get("sparkIQRegistered").process(packet);
} }
} }
// else if (packet instanceof Presence) {
// if (packet.getFrom().toString().equals(_mySubdomain)
// &&
// !JiveGlobals.getBooleanProperty("plugin.remoteroster.persistent",
// false)) {
// System.out.println("MACH EIN CLEANUP!!!!!!");
// _packetProcessor.get("handleCleanUp").process(packet);
// }
// }
} }
} }
/**
* Search the specified document for Nodes corresponding to the xpath Keep
* in mind that you have to use xmpp namespace for searching e.g.
* '//roster:features'
*
* @param doc
* document
* @param xpath
* with roster namespace for searching in query nodes
* @return list of nodes
*/
protected List<Node> findNodesInDocument(Document doc, String xpath)
{
Map<String, String> namespaceUris = new HashMap<String, String>();
namespaceUris.put("roster", "jabber:iq:roster");
namespaceUris.put("register", "jabber:iq:register");
XPath xPath = DocumentHelper.createXPath(xpath);
xPath.setNamespaceURIs(namespaceUris);
return xPath.selectNodes(doc);
}
protected String getServerNameFromComponentName(String componentName)
{
int intServer = componentName.lastIndexOf(".");
return componentName.substring(0, intServer);
}
} }
...@@ -8,10 +8,8 @@ import java.util.Map; ...@@ -8,10 +8,8 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import org.dom4j.Document; import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element; import org.dom4j.Element;
import org.dom4j.Node; import org.dom4j.Node;
import org.dom4j.XPath;
import org.jivesoftware.openfire.SessionManager; import org.jivesoftware.openfire.SessionManager;
import org.jivesoftware.openfire.component.ComponentEventListener; import org.jivesoftware.openfire.component.ComponentEventListener;
import org.jivesoftware.openfire.component.InternalComponentManager; import org.jivesoftware.openfire.component.InternalComponentManager;
...@@ -86,7 +84,7 @@ public class RemoteRosterPlugin implements Plugin { ...@@ -86,7 +84,7 @@ public class RemoteRosterPlugin implements Plugin {
if (_waitingForIQResponse.contains(from)) { if (_waitingForIQResponse.contains(from)) {
Element packet = iq.getChildElement(); Element packet = iq.getChildElement();
Document doc = packet.getDocument(); Document doc = packet.getDocument();
List<Node> nodes = findNodesInDocument(doc, "//xmpp:identity[@category='gateway']"); List<Node> nodes = Utils.findNodesInDocument(doc, "//disco:identity[@category='gateway']");
//Is this external component a gateway and there is no package interceptor for it? //Is this external component a gateway and there is no package interceptor for it?
if (nodes.size() > 0 && !_interceptors.containsKey(from)) if (nodes.size() > 0 && !_interceptors.containsKey(from))
{ {
...@@ -151,22 +149,6 @@ public class RemoteRosterPlugin implements Plugin { ...@@ -151,22 +149,6 @@ public class RemoteRosterPlugin implements Plugin {
} }
/**
* Search the specified document for Nodes corresponding to the xpath
* Keep in mind that you have to use xmpp namespace for searching e.g. '//xmpp:features'
* @param doc document
* @param xpath with xmpp namespace for searching in query nodes
* @return list of nodes
*/
private List<Node> findNodesInDocument(Document doc, String xpath)
{
Map<String, String> namespaceUris = new HashMap<String, String>();
namespaceUris.put("xmpp", "http://jabber.org/protocol/disco#info");
XPath xPath = DocumentHelper.createXPath(xpath);
xPath.setNamespaceURIs(namespaceUris);
return xPath.selectNodes(doc);
}
public static PluginManager getPluginManager() public static PluginManager getPluginManager()
{ {
return pluginManager; return pluginManager;
......
package org.jivesoftware.openfire.plugin;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Node;
import org.dom4j.XPath;
public class Utils {
/**
* Search the specified document for Nodes corresponding to the xpath Keep
* in mind that you have to use xmpp namespace for searching
* Predefined namespaces:
* jabber:iq:roster //roster:*
* jabber:iq:register //register:*
* http://jabber.org/protocol/disco#info //disco/*
* e.g
* '//roster:features'
*
* @param doc
* document
* @param xpath
* with roster namespace for searching in query nodes
* @return list of nodes found by xpath expression
*/
@SuppressWarnings("unchecked")
public static List<Node> findNodesInDocument(Document doc, String xpath)
{
Map<String, String> namespaceUris = new HashMap<String, String>();
namespaceUris.put("roster", "jabber:iq:roster");
namespaceUris.put("register", "jabber:iq:register");
namespaceUris.put("disco", "http://jabber.org/protocol/disco#info");
XPath xPath = DocumentHelper.createXPath(xpath);
xPath.setNamespaceURIs(namespaceUris);
return xPath.selectNodes(doc);
}
/**
* Returns the username from the given jid. user.name@jabber.server.org
* returns "user.name"
*
* @param jid
* @return the extracted username as string
*/
public static String getUsernameFromJid(String jid)
{
int firstAtPos = jid.indexOf("@");
return firstAtPos != -1 ? jid.substring(0, firstAtPos) : jid;
}
}
package org.jivesoftware.openfire.plugin.packageProcessor; package org.jivesoftware.openfire.plugin.packageProcessor;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import org.dom4j.Document; import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Node; import org.dom4j.Node;
import org.dom4j.XPath;
import org.jivesoftware.openfire.PacketRouter; import org.jivesoftware.openfire.PacketRouter;
import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.interceptor.PacketRejectedException; import org.jivesoftware.openfire.interceptor.PacketRejectedException;
import org.jivesoftware.openfire.plugin.Utils;
import org.xmpp.packet.Packet; import org.xmpp.packet.Packet;
abstract public class AbstractRemoteRosterProcessor { abstract public class AbstractRemoteRosterProcessor {
...@@ -31,37 +28,14 @@ abstract public class AbstractRemoteRosterProcessor { ...@@ -31,37 +28,14 @@ abstract public class AbstractRemoteRosterProcessor {
router.route(packet); router.route(packet);
} }
/**
* Search the specified document for Nodes corresponding to the xpath Keep
* in mind that you have to use xmpp namespace for searching e.g.
* '//roster:features'
*
* @param doc
* document
* @param xpath
* with roster namespace for searching in query nodes
* @return list of nodes
*/
protected List<Node> findNodesInDocument(Document doc, String xpath) protected List<Node> findNodesInDocument(Document doc, String xpath)
{ {
Map<String, String> namespaceUris = new HashMap<String, String>(); return Utils.findNodesInDocument(doc, xpath);
namespaceUris.put("roster", "jabber:iq:roster");
XPath xPath = DocumentHelper.createXPath(xpath);
xPath.setNamespaceURIs(namespaceUris);
return xPath.selectNodes(doc);
} }
protected String getUsernameFromJid(String jid) protected String getUsernameFromJid(String jid)
{ {
int firstAtPos = jid.indexOf("@"); return Utils.getUsernameFromJid(jid);
return firstAtPos != -1 ? jid.substring(0, firstAtPos) : jid;
}
protected String getServerNameFromComponentName(String componentName)
{
int intServer = componentName.lastIndexOf(".");
return componentName.substring(0, intServer);
} }
} }
package org.jivesoftware.openfire.plugin.packageProcessor;
import java.util.Collection;
import org.jivesoftware.openfire.interceptor.PacketRejectedException;
import org.jivesoftware.openfire.roster.Roster;
import org.jivesoftware.openfire.roster.RosterItem;
import org.jivesoftware.openfire.roster.RosterManager;
import org.xmpp.packet.Packet;
import org.xmpp.packet.Presence;
public class CleanUpRosterProcessor extends AbstractRemoteRosterProcessor {
private RosterManager _rosterManager;
private String _subDomain;
public CleanUpRosterProcessor(RosterManager rostermananger, String subdomain) {
_rosterManager = rostermananger;
_subDomain = subdomain;
}
@Override
public void process(Packet packet) throws PacketRejectedException
{
// System.out.println("hab hier was ne oder was");
Presence myPacket = (Presence) packet;
String to = myPacket.getTo().toString();
String username = getUsernameFromJid(to);
//<presence id="19nTS-48" to="xmpp.dew08299" type="unavailable"/
if (myPacket.getType() != null && myPacket.getType().equals(Presence.Type.unavailable))
{
System.out.println("is unavaibale ------------");
try {
Roster roster = _rosterManager.getRoster(username);
Collection <RosterItem> items = roster.getRosterItems();
for (RosterItem item: items)
{
String itemName = item.getJid().toString();
System.out.println("NAME: "+itemName+ " sub: "+_subDomain);
if (itemName.contains(_subDomain) && !itemName.equals(_subDomain))
{
System.out.println("entferne "+itemName);
roster.deleteRosterItem(item.getJid(), false);
}
}
} catch (Exception e) {
System.out.println("hier lief was falsch");
e.printStackTrace();
}
}
}
}
package org.jivesoftware.openfire.plugin.packageProcessor;
import org.dom4j.Element;
import org.dom4j.Node;
import org.jivesoftware.openfire.interceptor.PacketRejectedException;
import org.xmpp.packet.IQ;
import org.xmpp.packet.Packet;
public class ClientToComponentUpdateProcessor extends AbstractRemoteRosterProcessor {
private String _myDomain;
public ClientToComponentUpdateProcessor(String mySubdomain) {
_myDomain = mySubdomain;
}
@Override
public void process(Packet packet) throws PacketRejectedException
{
Element query = ((IQ) packet).getChildElement();
if (query != null && query.getNamespaceURI().equals("jabber:iq:roster")) {
if (findNodesInDocument(query.getDocument(), "//roster:item").size() > 0) {
for (Node n : findNodesInDocument(query.getDocument(), "//roster:item")) {
String jid = n.valueOf("@jid");
// TODO: We ignore remove iq packets for now. There might be
// conflicts
// when we remove our legacy network registration.
if (jid.contains("@" + _myDomain) && !n.valueOf("@subscription").equals("remove")) {
IQ forward = (IQ) packet.createCopy();
forward.setTo(_myDomain);
dispatchPacket(forward);
}
}
}
}
}
}
...@@ -47,6 +47,9 @@ public class DiscoIQResigteredProcessor extends AbstractRemoteRosterProcessor { ...@@ -47,6 +47,9 @@ public class DiscoIQResigteredProcessor extends AbstractRemoteRosterProcessor {
if (!processed && incoming) { if (!processed && incoming) {
if (packet instanceof IQ) { if (packet instanceof IQ) {
IQ iqPacket = (IQ) packet; IQ iqPacket = (IQ) packet;
Element packetElement = iqPacket.getChildElement();
if (packetElement == null)
return;
String ns = iqPacket.getChildElement().getNamespace().getURI(); String ns = iqPacket.getChildElement().getNamespace().getURI();
if (iqPacket.getType().equals(IQ.Type.result) && ns.equals("jabber:iq:register") if (iqPacket.getType().equals(IQ.Type.result) && ns.equals("jabber:iq:register")
&& iqPacket.getFrom().toString().equals(_mySubdoman)) { && iqPacket.getFrom().toString().equals(_mySubdoman)) {
......
...@@ -48,13 +48,15 @@ public class ReceiveComponentUpdatesProcessor extends AbstractRemoteRosterProces ...@@ -48,13 +48,15 @@ public class ReceiveComponentUpdatesProcessor extends AbstractRemoteRosterProces
String groupName = ne.getText(); String groupName = ne.getText();
grouplist.add(groupName); grouplist.add(groupName);
} }
boolean rosterPersisten = JiveGlobals.getBooleanProperty("plugin.remoteroster.persistent", false); boolean rosterPersisten = JiveGlobals.getBooleanProperty("plugin.remoteroster.persistent", true);
roster.createRosterItem(new JID(jid), name, grouplist, true, rosterPersisten); // System.out.println("fge item hinzu: "+jid+" mit gruppen: "+grouplist.toString());
RosterItem getThat = roster.getRosterItem(new JID(jid)); RosterItem item = roster.createRosterItem(new JID(jid), name, grouplist, false, rosterPersisten);
getThat.setSubStatus(RosterItem.SUB_BOTH); //RosterItem getThat = roster.getRosterItem(new JID(jid));
roster.updateRosterItem(getThat); item.setSubStatus(RosterItem.SUB_BOTH);
roster.updateRosterItem(item);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
System.out.println("Exception beim hinzufuegen eines Konaktes!");
} }
} }
} }
......
...@@ -28,7 +28,6 @@ public class SendRosterProcessor extends AbstractRemoteRosterProcessor { ...@@ -28,7 +28,6 @@ public class SendRosterProcessor extends AbstractRemoteRosterProcessor {
{ {
IQ myPacket = (IQ) packet; IQ myPacket = (IQ) packet;
String from = myPacket.getFrom().toString();
String to = myPacket.getFrom().toString(); String to = myPacket.getFrom().toString();
String username = getUsernameFromJid(to); String username = getUsernameFromJid(to);
...@@ -48,10 +47,9 @@ public class SendRosterProcessor extends AbstractRemoteRosterProcessor { ...@@ -48,10 +47,9 @@ public class SendRosterProcessor extends AbstractRemoteRosterProcessor {
IQ response = IQ.createResultIQ(iq); IQ response = IQ.createResultIQ(iq);
response.setTo(_componentName); response.setTo(_componentName);
Element query = new DefaultElement("query"); Element query = new DefaultElement("query");
for (RosterItem i : items) { for (RosterItem i : items) {
CharSequence serverName = getServerNameFromComponentName(_componentName); if (i.getJid().toString().contains(_componentName)) {
if (i.getJid().toString().contains(serverName)) { System.out.println("roster exchange: habe: "+i.getJid().toString());
Element item = new DefaultElement("item"); Element item = new DefaultElement("item");
item.add(new DefaultAttribute("jid", i.getJid().toString())); item.add(new DefaultAttribute("jid", i.getJid().toString()));
item.add(new DefaultAttribute("name", i.getNickname())); item.add(new DefaultAttribute("name", i.getNickname()));
...@@ -66,6 +64,7 @@ public class SendRosterProcessor extends AbstractRemoteRosterProcessor { ...@@ -66,6 +64,7 @@ public class SendRosterProcessor extends AbstractRemoteRosterProcessor {
} }
query.addNamespace("", "jabber:iq:roster"); query.addNamespace("", "jabber:iq:roster");
response.setChildElement(query); response.setChildElement(query);
System.out.println("sende response: "+response.toString());
dispatchPacket(response); dispatchPacket(response);
} }
......
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