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

[GATE-110] Added ability to move msn contacts between groups.

JML update.
Code cleanup.

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk/src/plugins/gateway@6034 b35dd754-fafc-0310-a699-88a17e54d16e
parent fdeb2b38
No preview for this file type
......@@ -2,7 +2,7 @@ Name | Version
---------------------------------------------
cindy.jar | 2.4.4
irclib.jar | 1.10
jml.jar | svn-20061107
jml.jar | svn-20061109
joscar-client.jar | svn-20061103
joscar-common.jar | svn-20061026
joscar-protocol.jar | svn-20061103
......
......@@ -15,13 +15,11 @@ import org.dom4j.Element;
import org.dom4j.QName;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.NotFoundException;
import org.jivesoftware.wildfire.ClientSession;
import org.jivesoftware.wildfire.SessionManager;
import org.jivesoftware.wildfire.XMPPServer;
import org.jivesoftware.wildfire.container.PluginManager;
import org.jivesoftware.wildfire.roster.Roster;
import org.jivesoftware.wildfire.roster.*;
import org.jivesoftware.wildfire.user.PresenceEventListener;
import org.jivesoftware.wildfire.user.UserAlreadyExistsException;
import org.jivesoftware.wildfire.user.UserNotFoundException;
import org.xmpp.component.Component;
......@@ -43,7 +41,7 @@ import java.util.*;
*
* @author Daniel Henninger
*/
public abstract class BaseTransport implements Component, RosterEventListener, PresenceEventListener {
public abstract class BaseTransport implements Component, RosterEventListener {
/**
* Create a new BaseTransport instance.
......@@ -399,7 +397,7 @@ public abstract class BaseTransport implements Component, RosterEventListener, P
reply.addAll(handleIQVersion(packet));
}
else {
Log.debug("Unable to handle iq request:" + xmlns);
Log.debug("Unable to handle iq request: " + xmlns);
IQ error = IQ.createResultIQ(packet);
error.setError(Condition.bad_request);
reply.add(error);
......@@ -1374,7 +1372,7 @@ public abstract class BaseTransport implements Component, RosterEventListener, P
}
try {
TransportSession session = sessionManager.getSession(roster.getUsername());
if (!session.isRosterLocked()) {
if (!session.isRosterLocked(item.getJid().toString())) {
Log.debug(getType().toString()+": contactUpdated "+roster.getUsername()+":"+item.getJid());
session.updateContact(item);
}
......@@ -1400,7 +1398,7 @@ public abstract class BaseTransport implements Component, RosterEventListener, P
}
try {
TransportSession session = sessionManager.getSession(roster.getUsername());
if (!session.isRosterLocked()) {
if (!session.isRosterLocked(item.getJid().toString())) {
Log.debug(getType().toString()+": contactAdded "+roster.getUsername()+":"+item.getJid());
session.addContact(item);
}
......@@ -1426,7 +1424,7 @@ public abstract class BaseTransport implements Component, RosterEventListener, P
}
try {
TransportSession session = sessionManager.getSession(roster.getUsername());
if (!session.isRosterLocked()) {
if (!session.isRosterLocked(item.getJid().toString())) {
Log.debug(getType().toString()+": contactDeleted "+roster.getUsername()+":"+item.getJid());
session.removeContact(item);
}
......@@ -1446,194 +1444,6 @@ public abstract class BaseTransport implements Component, RosterEventListener, P
// Don't care
}
/**
* Handles a session coming online (available).
*
* @see org.jivesoftware.wildfire.user.PresenceEventListener#availableSession(org.jivesoftware.wildfire.ClientSession, org.xmpp.packet.Presence)
*/
public void availableSession(ClientSession clSession, Presence packet) {
// Log.debug(getType().toString()+": availableSession "+clSession+":"+packet);
// JID from = packet.getFrom();
//
// Collection<Registration> registrations = registrationManager.getRegistrations(from, this.transportType);
// if (registrations.isEmpty()) {
// // User is not registered with us.
// return;
// }
// Registration registration = registrations.iterator().next();
//
// // A user's resource has come online.
// TransportSession session;
// try {
// session = sessionManager.getSession(from);
//
// if (session.hasResource(from.getResource())) {
// Log.debug("An existing resource has changed status: " + from);
//
// if (session.getPriority(from.getResource()) != packet.getPriority()) {
// session.updatePriority(from.getResource(), packet.getPriority());
// }
// if (session.isHighestPriority(from.getResource())) {
// // Well, this could represent a status change.
// session.updateStatus(getPresenceType(packet), packet.getStatus());
// }
// }
// else {
// Log.debug("A new resource has come online: " + from);
//
// // This is a new resource, lets send them what we know.
// session.addResource(from.getResource(), packet.getPriority());
// // Tell the new resource what the state of their buddy list is.
// session.resendContactStatuses(from);
// // If this priority is the highest, treat it's status as golden
// if (session.isHighestPriority(from.getResource())) {
// session.updateStatus(getPresenceType(packet), packet.getStatus());
// }
// }
// }
// catch (NotFoundException e) {
// Log.debug("A new session has come online: " + from);
//
// session = this.registrationLoggedIn(registration, from, getPresenceType(packet), packet.getStatus(), packet.getPriority());
// sessionManager.storeSession(from, session);
//
// }
}
/**
* Handles a session going offline (unavailable).
*
* @see org.jivesoftware.wildfire.user.PresenceEventListener#unavailableSession(org.jivesoftware.wildfire.ClientSession, org.xmpp.packet.Presence)
*/
public void unavailableSession(ClientSession clSession, Presence packet) {
// Log.debug(getType().toString()+": unavailableSession "+clSession+":"+packet);
// JID from = packet.getFrom();
//
// Collection<Registration> registrations = registrationManager.getRegistrations(from, this.transportType);
// if (registrations.isEmpty()) {
// // User is not registered with us.
// return;
// }
//
// // A user's resource has gone offline.
// TransportSession session;
// try {
// session = sessionManager.getSession(from);
// if (session.getResourceCount() > 1) {
// String resource = from.getResource();
//
// // Just one of the resources, lets adjust accordingly.
// if (session.isHighestPriority(resource)) {
// Log.debug("A high priority resource (of multiple) has gone offline: " + from);
//
// // Ooh, the highest resource went offline, drop to next highest.
// session.removeResource(resource);
//
// // Lets check the next highest resource for what it's presence is.
// SessionManager sessionManager = SessionManager.getInstance();
// String user = from.getNode();
// String nextResource = session.getJIDWithHighestPriority().getResource();
// if (sessionManager.getSessionCount(user) > 0) {
// for (ClientSession cSession : sessionManager.getSessions(user)) {
// Presence p = cSession.getPresence();
// if (p.getFrom().getResource().equals(nextResource)) {
// presenceChanged(cSession, cSession.getPresence());
// }
// }
// }
// }
// else {
// Log.debug("A low priority resource (of multiple) has gone offline: " + from);
//
// // Meh, lower priority, big whoop.
// session.removeResource(resource);
// }
// }
// else {
// Log.debug("A final resource has gone offline: " + from);
//
// // No more resources, byebye.
// if (session.isLoggedIn()) {
// this.registrationLoggedOut(session);
// }
//
// sessionManager.removeSession(from);
// }
// }
// catch (NotFoundException e) {
// Log.debug("Ignoring unavailable presence for inactive seession.");
// }
}
/**
* Handles a session's priority changing.
*
* @see org.jivesoftware.wildfire.user.PresenceEventListener#presencePriorityChanged(org.jivesoftware.wildfire.ClientSession, org.xmpp.packet.Presence)
*/
public void presencePriorityChanged(ClientSession clSession, Presence packet) {
// Log.debug(getType().toString()+": presencePriorityChanged "+clSession+":"+packet);
// JID from = packet.getFrom();
//
// Collection<Registration> registrations = registrationManager.getRegistrations(from, this.transportType);
// if (registrations.isEmpty()) {
// // User is not registered with us.
// return;
// }
//
// TransportSession session;
// try {
// session = sessionManager.getSession(from);
//
// if (session.hasResource(from.getResource())) {
// Log.debug("An existing resource has changed status: " + from);
//
// if (session.getPriority(from.getResource()) != packet.getPriority()) {
// session.updatePriority(from.getResource(), packet.getPriority());
// }
// if (session.isHighestPriority(from.getResource())) {
// // Well, this could represent a status change.
// session.updateStatus(getPresenceType(packet), packet.getStatus());
// }
// }
// }
// catch (NotFoundException e) {
// // Not actually logged in.
// }
}
/**
* Handles a session's status changing.
*
* @see org.jivesoftware.wildfire.user.PresenceEventListener#presenceChanged(org.jivesoftware.wildfire.ClientSession, org.xmpp.packet.Presence)
*/
public void presenceChanged(ClientSession clSession, Presence packet) {
// Log.debug(getType().toString()+": presenceChanged "+clSession+":"+packet);
// JID from = packet.getFrom();
//
// Collection<Registration> registrations = registrationManager.getRegistrations(from, this.transportType);
// if (registrations.isEmpty()) {
// // User is not registered with us.
// return;
// }
//
// TransportSession session;
// try {
// session = sessionManager.getSession(from);
//
// if (session.hasResource(from.getResource())) {
// Log.debug("An existing resource has changed status: " + from);
//
// if (session.isHighestPriority(from.getResource())) {
// // Well, this could represent a status change.
// session.updateStatus(getPresenceType(packet), packet.getStatus());
// }
// }
// }
// catch (NotFoundException e) {
// // Not actually logged in.
// }
}
/**
* Will handle logging in to the legacy service.
*
......
......@@ -91,6 +91,11 @@ public abstract class TransportSession implements Runnable {
*/
public boolean rosterLocked = false;
/**
* Contains a list of specific roster items that are locked.
*/
public ArrayList<String> rosterItemsLocked = new ArrayList<String>();
/**
* The current login status on the legacy network.
*/
......@@ -175,12 +180,35 @@ public abstract class TransportSession implements Runnable {
}
/**
* Locks the roster (typically used for editing during syncing.
* Returns if a specific roster item is currently locked.
*
* Also checks global lock.
*
* @param jid JID to check whether it's locked.
* @return true or false if the roster item is locked.
*/
public boolean isRosterLocked(String jid) {
return rosterLocked || rosterItemsLocked.contains(jid);
}
/**
* Locks the roster (typically used for editing during syncing).
*/
public void lockRoster() {
rosterLocked = true;
}
/**
* Locks a specific roster item (typically used for direct roster item updates).
*
* @param jid JID to lock.
*/
public void lockRoster(String jid) {
if (!rosterItemsLocked.contains(jid)) {
rosterItemsLocked.add(jid);
}
}
/**
* Unlocks the roster after sync editing is complete.
*/
......@@ -188,6 +216,17 @@ public abstract class TransportSession implements Runnable {
rosterLocked = false;
}
/**
* Unlocks a specific roster item.
*
* @param jid JID to unlock.
*/
public void unlockRoster(String jid) {
if (rosterItemsLocked.contains(jid)) {
rosterItemsLocked.remove(jid);
}
}
/**
* Retrieves the registration information associated with the session.
*
......
......@@ -166,6 +166,24 @@ public class MSNListener extends MsnAdapter {
msnSession.getTransport().sendPacket(p);
}
/**
* A contact we added has been added to the server.
*/
public void contactAddCompleted(MsnMessenger messenger, MsnContact contact) {
Log.debug("MSN: Contact add completed: "+contact);
msnSession.storeFriend(contact);
msnSession.completedPendingContactAdd(contact);
}
/**
* A group we added has been added to the server.
*/
public void groupAddCompleted(MsnMessenger messenger, MsnGroup group) {
Log.debug("MSN: Group add completed: "+group);
msnSession.storeGroup(group);
msnSession.completedPendingGroupAdd(group);
}
/**
* Owner status has changed.
*/
......
......@@ -17,10 +17,12 @@ import org.jivesoftware.util.Log;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.wildfire.gateway.*;
import org.jivesoftware.wildfire.roster.RosterItem;
import org.jivesoftware.wildfire.roster.Roster;
import org.jivesoftware.wildfire.user.UserNotFoundException;
import org.xmpp.packet.JID;
import org.xmpp.packet.PacketError;
import org.xmpp.packet.Presence;
import org.xmpp.packet.Message;
import java.util.ArrayList;
import java.util.List;
......@@ -47,6 +49,15 @@ public class MSNSession extends TransportSession {
public MSNSession(Registration registration, JID jid, MSNTransport transport, Integer priority) {
super(registration, jid, transport, priority);
if (Email.parseStr(registration.getUsername()) == null) {
Message m = new Message();
m.setType(Message.Type.error);
m.setTo(getJID());
m.setFrom(getTransport().getJID());
m.setBody("You are registered with the MSN transport with an illegal account name.\nThe account name should look like an email address.\nYou registered as:"+registration.getUsername());
return;
}
Log.debug("Creating MSN session for " + registration.getUsername());
msnMessenger = MsnMessengerFactory.createMsnMessenger(registration.getUsername(), registration.getPassword());
((BasicMessenger)msnMessenger).addSessionListener(new MsnSessionListener(this));
......@@ -68,6 +79,11 @@ public class MSNSession extends TransportSession {
*/
private ConcurrentHashMap<String,MsnGroup> msnGroups = new ConcurrentHashMap<String,MsnGroup>();
/**
* Pending MSN groups and contact to be added.
*/
private ConcurrentHashMap<String,ArrayList<Email>> msnPendingGroups = new ConcurrentHashMap<String,ArrayList<Email>>();
/**
* Log in to MSN.
*
......@@ -135,6 +151,72 @@ public class MSNSession extends TransportSession {
msnGroups.put(msnGroup.getGroupName(), msnGroup);
}
/**
* Records a member of a pending new group that will be added later.
*
* @param groupName Name of group to be stored.
* @param member Email address of member to be added.
*/
public void storePendingGroup(String groupName, Email member) {
if (!msnPendingGroups.containsKey(groupName)) {
ArrayList<Email> newList = new ArrayList<Email>();
newList.add(member);
msnPendingGroups.put(groupName, newList);
}
else {
ArrayList<Email> list = msnPendingGroups.get(groupName);
list.add(member);
msnPendingGroups.put(groupName, list);
}
}
/**
* Completes the addition of groups to a new contact after the contact has been created.
*
* @param msnContact Contact that was added.
*/
public void completedPendingContactAdd(MsnContact msnContact) {
try {
Roster roster = getTransport().getRosterManager().getRoster(getJID().getNode());
Email contact = msnContact.getEmail();
JID contactJID = getTransport().convertIDToJID(contact.toString());
RosterItem item = roster.getRosterItem(contactJID);
syncContactGroups(contact, item.getGroups());
unlockRoster(contactJID.toString());
}
catch (UserNotFoundException e) {
Log.error("MSN: Unable to find roster when adding pendingcontact for "+getJID());
Email contact = msnContact.getEmail();
JID contactJID = getTransport().convertIDToJID(contact.toString());
unlockRoster(contactJID.toString());
}
}
/**
* Completes the addition of a contact to a new group after the group has been created.
*
* @param msnGroup Group that was added.
*/
public void completedPendingGroupAdd(MsnGroup msnGroup) {
if (!msnPendingGroups.containsKey(msnGroup.getGroupName())) {
// Nothing to do, no pending.
return;
}
try {
Roster roster = getTransport().getRosterManager().getRoster(getJID().getNode());
for (Email contact : msnPendingGroups.get(msnGroup.getGroupName())) {
JID contactJID = getTransport().convertIDToJID(contact.toString());
RosterItem item = roster.getRosterItem(contactJID);
lockRoster(contactJID.toString());
syncContactGroups(contact, item.getGroups());
unlockRoster(contactJID.toString());
}
}
catch (UserNotFoundException e) {
Log.error("MSN: Unable to find roster when adding pending group contacts for "+getJID());
}
}
/**
* Syncs up the MSN roster with the jabber roster.
*/
......@@ -175,20 +257,23 @@ public class MSNSession extends TransportSession {
*/
public void addContact(RosterItem item) {
Email contact = Email.parseStr(getTransport().convertJIDToID(item.getJid()));
if (contact == null) {
Log.error("MSN: Unable to update illegal contact "+item.getJid());
return;
}
String nickname = getTransport().convertJIDToID(item.getJid());
if (item.getNickname() != null && !item.getNickname().equals("")) {
nickname = item.getNickname();
}
lockRoster(item.getJid().toString());
msnMessenger.addFriend(contact, nickname);
try {
lockRoster();
getTransport().addOrUpdateRosterItem(getJID(), item.getJid(), nickname, item.getGroups());
unlockRoster();
}
catch (UserNotFoundException e) {
Log.error("MSN: Unable to find roster when adding contact.");
}
syncContactGroups(contact, item.getGroups());
// syncContactGroups(contact, item.getGroups());
}
/**
......@@ -196,7 +281,14 @@ public class MSNSession extends TransportSession {
*/
public void removeContact(RosterItem item) {
Email contact = Email.parseStr(getTransport().convertJIDToID(item.getJid()));
if (contact == null) {
Log.error("MSN: Unable to update illegal contact "+item.getJid());
return;
}
lockRoster(item.getJid().toString());
msnMessenger.removeFriend(contact, false);
unlockRoster(item.getJid().toString());
msnContacts.remove(contact.toString());
}
/**
......@@ -204,6 +296,10 @@ public class MSNSession extends TransportSession {
*/
public void updateContact(RosterItem item) {
Email contact = Email.parseStr(getTransport().convertJIDToID(item.getJid()));
if (contact == null) {
Log.error("MSN: Unable to update illegal contact "+item.getJid());
return;
}
String nickname = getTransport().convertJIDToID(item.getJid());
if (item.getNickname() != null && !item.getNickname().equals("")) {
nickname = item.getNickname();
......@@ -212,10 +308,12 @@ public class MSNSession extends TransportSession {
if (msnContact == null) {
return;
}
lockRoster(item.getJid().toString());
if (!msnContact.getFriendlyName().equals(nickname)) {
msnMessenger.renameFriend(contact, nickname);
}
syncContactGroups(contact, item.getGroups());
unlockRoster(item.getJid().toString());
}
/**
......@@ -235,17 +333,16 @@ public class MSNSession extends TransportSession {
if (!msnGroups.containsKey(group)) {
Log.debug("MSN: Group "+group+" is a new group, creating.");
msnMessenger.addGroup(group);
// Ok, short circuit here, we need to wait for this group to be added. We'll be back.
storePendingGroup(group, contact);
return;
}
}
// 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) {
Log.debug("MSN: Found "+contact+" should belong to group "+group);
MsnGroup msnGroup = msnGroups.get(group);
if (!msnContact.belongGroup(msnGroup)) {
if (msnGroup != null && !msnContact.belongGroup(msnGroup)) {
Log.debug("MSN: "+contact+" does not belong to "+group+", copying.");
msnMessenger.copyFriend(contact, msnGroup.getGroupId());
}
......
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