Commit f506d3da authored by Daniel Henninger's avatar Daniel Henninger Committed by dhenninger

[GATE-3] Lots of reworking to handle nickname and group syncing. JML (MSN)...

[GATE-3] Lots of reworking to handle nickname and group syncing.  JML (MSN) doesn't support removing buddies yet.. (sigh)  OSCAR has a null exception error that's occuring when I add a new buddy that I need to track down.

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk@5236 b35dd754-fafc-0310-a699-88a17e54d16e
parent 2ce064c4
...@@ -719,6 +719,13 @@ public abstract class BaseTransport implements Component, RosterEventListener { ...@@ -719,6 +719,13 @@ public abstract class BaseTransport implements Component, RosterEventListener {
return this.jid; return this.jid;
} }
/**
* Returns the roster manager for the transport.
*/
public RosterManager getRosterManager() {
return this.rosterManager;
}
/** /**
* Returns the name (type) of the transport. * Returns the name (type) of the transport.
*/ */
......
...@@ -13,6 +13,7 @@ package org.jivesoftware.wildfire.gateway; ...@@ -13,6 +13,7 @@ package org.jivesoftware.wildfire.gateway;
import org.xmpp.packet.JID; import org.xmpp.packet.JID;
import org.jivesoftware.wildfire.user.UserNotFoundException; import org.jivesoftware.wildfire.user.UserNotFoundException;
import org.jivesoftware.wildfire.roster.RosterItem; import org.jivesoftware.wildfire.roster.RosterItem;
import org.jivesoftware.wildfire.roster.Roster;
import java.util.TreeMap; import java.util.TreeMap;
...@@ -134,7 +135,7 @@ public abstract class TransportSession implements Runnable { ...@@ -134,7 +135,7 @@ public abstract class TransportSession implements Runnable {
} }
/** /**
* Retrieves the transport associated wtih the session. * Retrieves the transport associated with the session.
* *
* @return Transport associated with the session. * @return Transport associated with the session.
*/ */
...@@ -142,6 +143,20 @@ public abstract class TransportSession implements Runnable { ...@@ -142,6 +143,20 @@ public abstract class TransportSession implements Runnable {
return transport; return transport;
} }
/**
* Retrieves the roster associated with the session.
*
* @return Roster associated with the session, or null if none.
*/
public Roster getRoster() {
try {
return getTransport().getRosterManager().getRoster(getJID().getNode());
}
catch (UserNotFoundException e) {
return null;
}
}
/** /**
* Retrieves the bare jid associated with the session. * Retrieves the bare jid associated with the session.
* *
......
...@@ -17,6 +17,7 @@ import net.sf.jml.event.MsnAdapter; ...@@ -17,6 +17,7 @@ import net.sf.jml.event.MsnAdapter;
import net.sf.jml.MsnSwitchboard; import net.sf.jml.MsnSwitchboard;
import net.sf.jml.MsnContact; import net.sf.jml.MsnContact;
import net.sf.jml.MsnMessenger; import net.sf.jml.MsnMessenger;
import net.sf.jml.MsnGroup;
import net.sf.jml.message.MsnInstantMessage; import net.sf.jml.message.MsnInstantMessage;
import net.sf.jml.message.MsnControlMessage; import net.sf.jml.message.MsnControlMessage;
import net.sf.jml.message.MsnDatacastMessage; import net.sf.jml.message.MsnDatacastMessage;
...@@ -121,6 +122,9 @@ public class MSNListener extends MsnAdapter { ...@@ -121,6 +122,9 @@ public class MSNListener extends MsnAdapter {
Log.debug("Got contact "+msnContact); Log.debug("Got contact "+msnContact);
msnSession.storeFriend(msnContact); msnSession.storeFriend(msnContact);
} }
for (MsnGroup msnGroup : messenger.getContactList().getGroups()) {
msnSession.storeGroup(msnGroup);
}
msnSession.syncUsers(); msnSession.syncUsers();
} }
......
...@@ -61,6 +61,11 @@ public class MSNSession extends TransportSession { ...@@ -61,6 +61,11 @@ public class MSNSession extends TransportSession {
*/ */
private HashMap<String,MsnContact> msnContacts = new HashMap<String,MsnContact>(); private HashMap<String,MsnContact> msnContacts = new HashMap<String,MsnContact>();
/**
* MSN groups.
*/
private HashMap<String,MsnGroup> msnGroups = new HashMap<String,MsnGroup>();
/** /**
* Login status * Login status
*/ */
...@@ -75,8 +80,8 @@ public class MSNSession extends TransportSession { ...@@ -75,8 +80,8 @@ public class MSNSession extends TransportSession {
public void logIn(PresenceType presenceType, String verboseStatus) { public void logIn(PresenceType presenceType, String verboseStatus) {
if (!this.isLoggedIn()) { if (!this.isLoggedIn()) {
msnMessenger.getOwner().setInitStatus(((MSNTransport)getTransport()).convertJabStatusToMSN(presenceType)); msnMessenger.getOwner().setInitStatus(((MSNTransport)getTransport()).convertJabStatusToMSN(presenceType));
msnMessenger.setLogIncoming(true); msnMessenger.setLogIncoming(false);
msnMessenger.setLogOutgoing(true); msnMessenger.setLogOutgoing(false);
msnMessenger.addListener(new MSNListener(this)); msnMessenger.addListener(new MSNListener(this));
msnMessenger.login(); msnMessenger.login();
} }
...@@ -124,6 +129,13 @@ public class MSNSession extends TransportSession { ...@@ -124,6 +129,13 @@ public class MSNSession extends TransportSession {
msnContacts.put(msnContact.getEmail().toString(), msnContact); msnContacts.put(msnContact.getEmail().toString(), msnContact);
} }
/**
* Records information about a group on the user's contact list.
*/
public void storeGroup(MsnGroup msnGroup) {
msnGroups.put(msnGroup.getGroupName(), msnGroup);
}
/** /**
* Syncs up the MSN roster with the jabber roster. * Syncs up the MSN roster with the jabber roster.
*/ */
...@@ -162,23 +174,77 @@ public class MSNSession extends TransportSession { ...@@ -162,23 +174,77 @@ public class MSNSession extends TransportSession {
* @see org.jivesoftware.wildfire.gateway.TransportSession#addContact(org.jivesoftware.wildfire.roster.RosterItem) * @see org.jivesoftware.wildfire.gateway.TransportSession#addContact(org.jivesoftware.wildfire.roster.RosterItem)
*/ */
public void addContact(RosterItem item) { public void addContact(RosterItem item) {
// @todo check jabber group and use it Email contact = Email.parseStr(getTransport().convertJIDToID(item.getJid()));
msnMessenger.addFriend(Email.parseStr(getTransport().convertJIDToID(item.getJid())), getTransport().convertJIDToID(item.getJid())); String nickname = getTransport().convertJIDToID(item.getJid());
if (item.getNickname() != null && !item.getNickname().equals("")) {
nickname = item.getNickname();
}
msnMessenger.addFriend(contact, nickname);
syncContactGroups(contact, item.getGroups());
} }
/** /**
* @see org.jivesoftware.wildfire.gateway.TransportSession#removeContact(org.jivesoftware.wildfire.roster.RosterItem) * @see org.jivesoftware.wildfire.gateway.TransportSession#removeContact(org.jivesoftware.wildfire.roster.RosterItem)
*/ */
public void removeContact(RosterItem item) { public void removeContact(RosterItem item) {
// @todo check jabber group and use it Email contact = Email.parseStr(getTransport().convertJIDToID(item.getJid()));
msnMessenger.removeFriend(Email.parseStr(getTransport().convertJIDToID(item.getJid())), false); // TODO: JML doesn't actually -do- removal yet. Dammit.
// Well lets at least run through the motions...
MsnContact msnContact = msnContacts.get(contact.toString());
for (MsnGroup msnGroup : msnContact.getBelongGroups()) {
msnMessenger.removeFriend(contact, msnGroup.getGroupId());
}
} }
/** /**
* @see org.jivesoftware.wildfire.gateway.TransportSession#updateContact(org.jivesoftware.wildfire.roster.RosterItem) * @see org.jivesoftware.wildfire.gateway.TransportSession#updateContact(org.jivesoftware.wildfire.roster.RosterItem)
*/ */
public void updateContact(RosterItem item) { public void updateContact(RosterItem item) {
// TODO: Implement this Email contact = Email.parseStr(getTransport().convertJIDToID(item.getJid()));
String nickname = getTransport().convertJIDToID(item.getJid());
if (item.getNickname() != null && !item.getNickname().equals("")) {
nickname = item.getNickname();
}
msnMessenger.renameFriend(contact, nickname);
syncContactGroups(contact, item.getGroups());
}
/**
* Given a legacy contact and a list of groups, makes sure that the list is in sync with
* the actual group list.
*
* @param contact Email address of contact.
* @param groups List of groups contact should be in.
*/
public void syncContactGroups(Email contact, List<String> groups) {
if (groups.isEmpty()) {
groups.add("Transport Buddies");
}
MsnContact msnContact = msnContacts.get(contact.toString());
// Create groups that do not currently exist.
for (String group : groups) {
if (!msnGroups.containsKey(group)) {
msnMessenger.addGroup(group);
}
}
// Lets update our list of groups.
for (MsnGroup msnGroup : msnMessenger.getContactList().getGroups()) {
storeGroup(msnGroup);
}
// Make sure contact belongs to groups that we want.
for (String group : groups) {
MsnGroup msnGroup = msnGroups.get(group);
if (!msnContact.belongGroup(msnGroup)) {
msnMessenger.copyFriend(contact, group);
}
}
// Now we will clean up groups that we should no longer belong to.
for (MsnGroup msnGroup : msnContact.getBelongGroups()) {
if (!groups.contains(msnGroup.getGroupName())) {
// TODO: This is not going to work. removeFriend is ignored.
msnMessenger.removeFriend(contact, msnGroup.getGroupId());
}
}
} }
/** /**
...@@ -210,7 +276,10 @@ public class MSNSession extends TransportSession { ...@@ -210,7 +276,10 @@ public class MSNSession extends TransportSession {
if (isLoggedIn()) { if (isLoggedIn()) {
msnMessenger.getOwner().setStatus(((MSNTransport)getTransport()).convertJabStatusToMSN(presenceType)); msnMessenger.getOwner().setStatus(((MSNTransport)getTransport()).convertJabStatusToMSN(presenceType));
} }
// TODO: Should I consider logging them in? else {
// Hrm, not logged in? Lets fix that.
msnMessenger.login();
}
} }
/** /**
......
...@@ -112,43 +112,93 @@ public class OSCARSession extends TransportSession { ...@@ -112,43 +112,93 @@ public class OSCARSession extends TransportSession {
} }
/** /**
* @see org.jivesoftware.wildfire.gateway.TransportSession#addContact(org.jivesoftware.wildfire.roster.RosterItem) * Finds the id number of a group specified or creates a new one and returns that id.
*
* @param groupName Name of the group we are looking for.
* @return Id number of the group.
*/ */
public void addContact(RosterItem item) { public Integer getGroupIdOrCreateNew(String groupName) {
Integer groupId = -1;
for (GroupItem g : groups.values()) { for (GroupItem g : groups.values()) {
if ("Transport Buddies".equals(g.getGroupName())) { if (groupName.equals(g.getGroupName())) {
groupId = g.getId(); return g.getId();
} }
} }
if (groupId == -1) { // Group doesn't exist, lets create a new one.
Integer newGroupId = highestGroupId + 1; Integer newGroupId = highestGroupId + 1;
GroupItem newGroup = new GroupItem("Transport Buddies", newGroupId); GroupItem newGroup = new GroupItem(groupName, newGroupId);
request(new CreateItemsCmd(new SsiItem[] { newGroup.toSsiItem() })); request(new CreateItemsCmd(new SsiItem[] { newGroup.toSsiItem() }));
highestGroupId = newGroupId; highestGroupId = newGroupId;
groupId = newGroupId; groups.put(newGroupId, newGroup);
groups.put(groupId, newGroup);
return newGroupId;
}
/**
* Synchronizes the list of groups a contact is a member of, updating nicknames in
* the process.
*
* @param contact Screen name/UIN of the contact.
* @param nickname Nickname of the contact (should not be null)
* @param grouplist List of groups the contact should be a member of.
*/
public void syncContactGroupsAndNickname(String contact, String nickname, List<String> grouplist) {
if (grouplist.isEmpty()) {
grouplist.add("Transport Buddies");
}
// First, lets take the known good list of groups and sync things up server side.
for (String group : grouplist) {
Integer groupId = getGroupIdOrCreateNew(group);
Integer newBuddyId = 1;
if (highestBuddyIdPerGroup.containsKey(groupId)) {
newBuddyId = highestBuddyIdPerGroup.get(groupId) + 1;
}
highestBuddyIdPerGroup.put(groupId, newBuddyId);
BuddyItem newBuddy = new BuddyItem(contact, newBuddyId, groupId);
newBuddy.setAlias(nickname);
request(new CreateItemsCmd(new SsiItem[] { newBuddy.toSsiItem() }));
buddies.put(groupId+"."+newBuddyId, newBuddy);
}
// Now, lets clean up any groups this contact should no longer be a member of.
for (BuddyItem buddy : buddies.values()) {
if (buddy.getScreenname().equals(contact)) {
if (!grouplist.contains(groups.get(buddy.getGroupId()).getGroupName())) {
request(new DeleteItemsCmd(new SsiItem[] { buddy.toSsiItem() }));
buddies.remove(buddy.getGroupId()+"."+buddy.getId());
}
else {
if (!buddy.getAlias().equals(nickname)) {
buddy.setAlias(nickname);
request(new ModifyItemsCmd(new SsiItem[] { buddy.toSsiItem() }));
}
}
}
} }
}
Integer newBuddyId = 1; /**
if (highestBuddyIdPerGroup.containsKey(groupId)) { * @see org.jivesoftware.wildfire.gateway.TransportSession#addContact(org.jivesoftware.wildfire.roster.RosterItem)
newBuddyId = highestBuddyIdPerGroup.get(groupId) + 1; */
public void addContact(RosterItem item) {
String legacyId = getTransport().convertJIDToID(item.getJid());
String nickname = item.getNickname();
if (nickname == null || nickname.equals("")) {
nickname = legacyId;
} }
highestBuddyIdPerGroup.put(groupId, newBuddyId);
BuddyItem newBuddy = new BuddyItem(getTransport().convertJIDToID(item.getJid()), newBuddyId, groupId); // Syncing takes care of all the dirty work.
request(new CreateItemsCmd(new SsiItem[] { newBuddy.toSsiItem() })); syncContactGroupsAndNickname(legacyId, nickname, item.getGroups());
buddies.put(groupId+"."+newBuddyId, newBuddy);
} }
/** /**
* @see org.jivesoftware.wildfire.gateway.TransportSession#removeContact(org.jivesoftware.wildfire.roster.RosterItem) * @see org.jivesoftware.wildfire.gateway.TransportSession#removeContact(org.jivesoftware.wildfire.roster.RosterItem)
*/ */
public void removeContact(RosterItem item) { public void removeContact(RosterItem item) {
String legacyId = getTransport().convertJIDToID(item.getJid());
for (BuddyItem i : buddies.values()) { for (BuddyItem i : buddies.values()) {
if (i.getScreenname().equals(getTransport().convertJIDToID(item.getJid()))) { if (i.getScreenname().equals(legacyId)) {
request(new DeleteItemsCmd(new SsiItem[] { i.toSsiItem() })); request(new DeleteItemsCmd(new SsiItem[] { i.toSsiItem() }));
buddies.remove(i.getGroupId()+"."+i.getId()); buddies.remove(i.getGroupId()+"."+i.getId());
} }
...@@ -159,7 +209,14 @@ public class OSCARSession extends TransportSession { ...@@ -159,7 +209,14 @@ public class OSCARSession extends TransportSession {
* @see org.jivesoftware.wildfire.gateway.TransportSession#updateContact(org.jivesoftware.wildfire.roster.RosterItem) * @see org.jivesoftware.wildfire.gateway.TransportSession#updateContact(org.jivesoftware.wildfire.roster.RosterItem)
*/ */
public void updateContact(RosterItem item) { public void updateContact(RosterItem item) {
// TODO: Implement this String legacyId = getTransport().convertJIDToID(item.getJid());
String nickname = item.getNickname();
if (nickname == null || nickname.equals("")) {
nickname = legacyId;
}
// Syncing takes care of all of the dirty work.
syncContactGroupsAndNickname(legacyId, nickname, item.getGroups());
} }
/** /**
...@@ -169,11 +226,23 @@ public class OSCARSession extends TransportSession { ...@@ -169,11 +226,23 @@ public class OSCARSession extends TransportSession {
request(new SendImIcbm(getTransport().convertJIDToID(jid), message)); request(new SendImIcbm(getTransport().convertJIDToID(jid), message));
} }
/**
* Opens/creates a new BOS connection to a specific server and port, given a cookie.
*
* @param server Server to connect to.
* @param port Port to connect to.
* @param cookie Auth cookie.
*/
void startBosConn(String server, int port, ByteBlock cookie) { void startBosConn(String server, int port, ByteBlock cookie) {
bosConn = new BOSConnection(server, port, this, cookie); bosConn = new BOSConnection(server, port, this, cookie);
bosConn.connect(); bosConn.connect();
} }
/**
* Registers the set of SNAC families that the given connection supports.
*
* @param conn FLAP connection to be registered.
*/
void registerSnacFamilies(BasicFlapConnection conn) { void registerSnacFamilies(BasicFlapConnection conn) {
snacMgr.register(conn); snacMgr.register(conn);
} }
......
...@@ -11,10 +11,8 @@ ...@@ -11,10 +11,8 @@
package org.jivesoftware.wildfire.gateway.protocols.yahoo; package org.jivesoftware.wildfire.gateway.protocols.yahoo;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.*;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.wildfire.gateway.PresenceType; import org.jivesoftware.wildfire.gateway.PresenceType;
import org.jivesoftware.wildfire.gateway.Registration; import org.jivesoftware.wildfire.gateway.Registration;
...@@ -195,33 +193,89 @@ public class YahooSession extends TransportSession { ...@@ -195,33 +193,89 @@ public class YahooSession extends TransportSession {
* @see org.jivesoftware.wildfire.gateway.TransportSession#addContact(org.jivesoftware.wildfire.roster.RosterItem) * @see org.jivesoftware.wildfire.gateway.TransportSession#addContact(org.jivesoftware.wildfire.roster.RosterItem)
*/ */
public void addContact(RosterItem item) { public void addContact(RosterItem item) {
// @todo check jabber group and use it // TODO: Sync nickname (local storage)
try { // Syncing will take are of add.
yahooSession.addFriend(item.getJid().getNode(), "Yahoo Transport"); String contact = getTransport().convertJIDToID(item.getJid());
} syncContactGroups(contact, item.getGroups());
catch (IOException e) {
Log.error("Failed to add yahoo user.");
}
} }
/** /**
* @see org.jivesoftware.wildfire.gateway.TransportSession#removeContact(org.jivesoftware.wildfire.roster.RosterItem) * @see org.jivesoftware.wildfire.gateway.TransportSession#removeContact(org.jivesoftware.wildfire.roster.RosterItem)
*/ */
public void removeContact(RosterItem item) { public void removeContact(RosterItem item) {
// @todo check jabber group and use it // TODO: Clear local stored nickname.
try { String contact = getTransport().convertJIDToID(item.getJid());
yahooSession.removeFriend(item.getJid().getNode(), "Yahoo Transport"); for (YahooGroup yahooGroup : yahooSession.getGroups()) {
} if (yahooGroup.getIndexOfFriend(contact) != -1) {
catch (IOException e) { try {
Log.error("Failed to remove yahoo user."); yahooSession.removeFriend(contact, yahooGroup.getName());
}
catch (IOException e) {
Log.error("Failed to remove yahoo user.");
}
}
} }
} }
/** /**
* @see org.jivesoftware.wildfire.gateway.TransportSession#updateContact(org.jivesoftware.wildfire.roster.RosterItem) * @see org.jivesoftware.wildfire.gateway.TransportSession#updateContact(org.jivesoftware.wildfire.roster.RosterItem)
*/ */
public void updateContact(RosterItem item) { public void updateContact(RosterItem item) {
// TODO: Do something here. // TODO: Sync nickname (local storage)
String contact = getTransport().convertJIDToID(item.getJid());
syncContactGroups(contact, item.getGroups());
}
/**
* Given a legacy contact and a list of groups, makes sure that the list is in sync with
* the actual group list.
*
* @param contact Email address of contact.
* @param groups List of groups contact should be in.
*/
public void syncContactGroups(String contact, List<String> groups) {
if (groups.isEmpty()) {
groups.add("Transport Buddies");
}
HashMap<String,YahooGroup> yahooGroups = new HashMap<String,YahooGroup>();
// Lets create a hash of these for easier reference.
for (YahooGroup yahooGroup : yahooSession.getGroups()) {
yahooGroups.put(yahooGroup.getName(), yahooGroup);
}
// Create groups(add user to them) that do not currently exist.
for (String group : groups) {
if (!yahooGroups.containsKey(group)) {
try {
yahooSession.addFriend(contact, group);
}
catch (IOException e) {
Log.error("Error while syncing Yahoo groups.");
}
}
}
// Now we handle adds and removes, syncing the two lists.
for (YahooGroup yahooGroup : yahooSession.getGroups()) {
if (groups.contains(yahooGroup.getName())) {
if (yahooGroup.getIndexOfFriend(contact) == -1) {
try {
yahooSession.addFriend(contact, yahooGroup.getName());
}
catch (IOException e) {
Log.error("Error while syncing Yahoo groups.");
}
}
}
else {
if (yahooGroup.getIndexOfFriend(contact) != -1) {
try {
yahooSession.removeFriend(contact, yahooGroup.getName());
}
catch (IOException e) {
Log.error("Error while syncing Yahoo groups.");
}
}
}
}
} }
/** /**
......
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