Issue #2563 roster updates for stock servers

added functionality that makes the contact list compatible with server rosters that could be modified with other clients
added support for roster entries that aren't in a local or server group


Former-commit-id: c5801f2e12 [formerly b41eadd0be] [formerly b120d74099] [formerly b120d74099 [formerly 2b8668a4eb]] [formerly e4bd8a3e2c [formerly b120d74099 [formerly 2b8668a4eb] [formerly e4bd8a3e2c [formerly 23d898308fb3aa673d85fdf00495d43e4c02a08f]]]]
Former-commit-id: e4bd8a3e2c
Former-commit-id: 8e5c8129c3d7ceb59dcf72334219b8c0bef23071 [formerly 35a2c84384d4302036ad4c4d8408a681edbf9e81] [formerly 0882672686 [formerly 4b4c7ba50c]]
Former-commit-id: 0882672686
Former-commit-id: f084679410
This commit is contained in:
Brian Clements 2013-12-20 11:48:19 -06:00
parent dbca2a4dd5
commit 9de38cb466
7 changed files with 249 additions and 55 deletions

View file

@ -20,8 +20,12 @@
package com.raytheon.uf.viz.collaboration.comm.provider.session;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException;
/**
* Manages roster from server
@ -33,6 +37,7 @@ import org.jivesoftware.smack.XMPPConnection;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 25, 2013 2561 bclement Initial creation
* Dec 20, 2013 2563 bclement added remove from roster method
*
* </pre>
*
@ -75,4 +80,21 @@ public class RosterManager {
getRoster().removeRosterListener(listener);
}
/**
* Remove entry from roster on server
*
* @param entry
* @throws CollaborationException
*/
public void removeFromRoster(RosterEntry entry)
throws CollaborationException {
Roster roster = getRoster();
try {
roster.removeEntry(entry);
} catch (XMPPException e) {
throw new CollaborationException(
"Problem removing user from roster on server", e);
}
}
}

View file

@ -21,7 +21,6 @@ package com.raytheon.uf.viz.collaboration.comm.provider.user;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@ -35,7 +34,6 @@ import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.jobs.Job;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterListener;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Presence.Type;
@ -68,6 +66,8 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.LocalGroups.LocalGro
* ------------ ---------- ----------- --------------------------
* Jun 29, 2012 bsteffen Initial creation
* Dec 6, 2013 2561 bclement removed ECF
* Dec 20, 2013 2563 bclement roster items now removed from server,
* removed unneeded roster listener
*
* </pre>
*
@ -121,36 +121,6 @@ public class ContactsManager {
this.search = connection.createSearch();
localAliases = UserIdWrapper.readAliasMap();
initLocalGroups();
final RosterManager rosterManager = connection.getRosterManager();
final Roster roster = rosterManager.getRoster();
// currently don't need to listen to roster since we only allow one
// client
rosterManager.addRosterListener(new RosterListener() {
@Override
public void entriesAdded(Collection<String> addresses) {
// TODO handle roster additions from other clients
}
@Override
public void entriesUpdated(Collection<String> addresses) {
// TODO Auto-generated method stub
}
@Override
public void entriesDeleted(Collection<String> addresses) {
// TODO Auto-generated method stub
}
@Override
public void presenceChanged(
org.jivesoftware.smack.packet.Presence presence) {
// TODO Auto-generated method stub
}
});
}
private void initLocalGroups() {
@ -237,15 +207,30 @@ public class ContactsManager {
try {
connection.getAccountManager().sendPresence(presence);
} catch (CollaborationException e) {
statusHandler.handle(Priority.PROBLEM,
e.getLocalizedMessage(), e);
statusHandler.error(
"Problem removing user from roster", e);
}
removeFromRoster(entry);
}
}
storeLocalGroupsJob.schedule();
}
}
/**
* Remove entry from roster on server
*
* @param entry
*/
public void removeFromRoster(RosterEntry entry) {
RosterManager rosterManager = connection.getRosterManager();
try {
rosterManager.removeFromRoster(entry);
} catch (CollaborationException e) {
statusHandler.error("Problem removing roster entry", e);
}
}
public LocalGroup createLocalGroup(String groupName) {
synchronized (localGroups) {
for (LocalGroup group : this.localGroups) {

View file

@ -110,6 +110,7 @@ import com.raytheon.uf.viz.collaboration.ui.actions.LoginAction;
import com.raytheon.uf.viz.collaboration.ui.actions.LogoutAction;
import com.raytheon.uf.viz.collaboration.ui.actions.PeerToPeerChatAction;
import com.raytheon.uf.viz.collaboration.ui.actions.RemoveFromGroupAction;
import com.raytheon.uf.viz.collaboration.ui.actions.RemoveFromRosterAction;
import com.raytheon.uf.viz.collaboration.ui.actions.ShowVenueAction;
import com.raytheon.uf.viz.collaboration.ui.actions.UserSearchAction;
import com.raytheon.uf.viz.collaboration.ui.data.AlertWordWrapper;
@ -134,6 +135,7 @@ import com.raytheon.viz.ui.views.CaveFloatingView;
* Oct 22, 2013 #2483 lvenable Fixed image memory leak.
* Dec 6, 2013 2561 bclement removed ECF
* Dec 19, 2013 2563 bclement added subscribe method for server disconnection
* Dec 20, 2013 2563 bclement fixed support for ungrouped roster items
*
* </pre>
*
@ -388,11 +390,16 @@ public class CollaborationGroupView extends CaveFloatingView implements
manager.add(new ArchiveViewerAction((IVenueSession) o));
return;
} else if (o instanceof RosterEntry) {
// roster entries that are not in a group
RosterEntry entry = (RosterEntry) o;
UserId user = IDConverter.convertFrom(entry);
fillContextMenu(manager, selection, user);
addOnlineMenuOptions(manager, selection, user);
addAliasAction(manager, selection, user);
manager.add(new ArchiveViewerAction(user));
manager.add(new AddToGroupAction(entry));
manager.add(new RemoveFromRosterAction(entry));
} else if (o instanceof UserId) {
// the user, both the logged in user as well as his buddies
// the user, both the logged in user as well as entries in groups
UserId user = (UserId) o;
fillContextMenu(manager, selection, user);
} else if (o instanceof RosterGroup || o instanceof LocalGroup) {
@ -407,6 +414,14 @@ public class CollaborationGroupView extends CaveFloatingView implements
}
}
/**
* Populate menu for roster entries. Checks for current user to create
* appropriate menu.
*
* @param manager
* @param selection
* @param user
*/
private void fillContextMenu(IMenuManager manager, TreeSelection selection,
UserId user) {
CollaborationConnection connection = CollaborationConnection
@ -416,9 +431,31 @@ public class CollaborationGroupView extends CaveFloatingView implements
createMenu(manager);
return;
}
addOnlineMenuOptions(manager, selection, user);
addAliasAction(manager, selection, user);
Presence presence = CollaborationConnection.getConnection()
.getContactsManager().getPresence(user);
manager.add(new ArchiveViewerAction(user));
manager.add(new AddToGroupAction(getSelectedUsers()));
String groupName = null;
Object group = selection.getPaths()[0].getFirstSegment();
if (group instanceof LocalGroup) {
groupName = ((LocalGroup) group).getName();
manager.add(new RemoveFromGroupAction(groupName, getSelectedUsers()));
}
}
/**
* Add interaction menu options for contact if they are online
*
* @param manager
* @param selection
* @param user
*/
private void addOnlineMenuOptions(IMenuManager manager,
TreeSelection selection, UserId user) {
CollaborationConnection connection = CollaborationConnection
.getConnection();
Presence presence = connection.getContactsManager().getPresence(user);
if (presence != null && presence.getType() == Type.available) {
Action inviteAction = new InviteAction(user);
if (inviteAction.isEnabled()) {
@ -431,19 +468,23 @@ public class CollaborationGroupView extends CaveFloatingView implements
manager.add(new Separator());
manager.add(createSessionAction);
}
String name = CollaborationConnection.getConnection()
.getContactsManager().getDisplayName(user);
}
/**
* Add menu option for aliasing username
*
* @param manager
* @param selection
* @param user
*/
private void addAliasAction(IMenuManager manager, TreeSelection selection,
UserId user) {
CollaborationConnection connection = CollaborationConnection
.getConnection();
String name = connection.getContactsManager().getDisplayName(user);
aliasAction.setId(name);
aliasAction.setText("Alias");
manager.add(aliasAction);
manager.add(new ArchiveViewerAction(user));
manager.add(new AddToGroupAction(getSelectedUsers()));
String groupName = null;
Object group = selection.getPaths()[0].getFirstSegment();
if (group instanceof LocalGroup) {
groupName = ((LocalGroup) group).getName();
manager.add(new RemoveFromGroupAction(groupName, getSelectedUsers()));
}
}
private void addDoubleClickListeners() {
@ -745,6 +786,9 @@ public class CollaborationGroupView extends CaveFloatingView implements
if (node instanceof UserId) {
UserId user = (UserId) node;
selectedUsers.add(user);
} else if (node instanceof RosterEntry) {
UserId user = IDConverter.convertFrom((RosterEntry) node);
selectedUsers.add(user);
} else if (node instanceof RosterGroup) {
selectedUsers.addAll(getSelectedUsers((RosterGroup) node));
} else if (node instanceof LocalGroup) {

View file

@ -42,12 +42,13 @@ import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException;
import com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession;
import com.raytheon.uf.viz.collaboration.comm.identity.info.IVenueInfo;
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter;
import com.raytheon.uf.viz.collaboration.comm.provider.user.LocalGroups.LocalGroup;
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
import com.raytheon.uf.viz.collaboration.ui.data.SessionGroupContainer;
/**
* TODO Add Description
* Provides contacts list UI elements with icons, text, tooltips, etc
*
* <pre>
*
@ -57,6 +58,7 @@ import com.raytheon.uf.viz.collaboration.ui.data.SessionGroupContainer;
* ------------ ---------- ----------- --------------------------
* Mar 1, 2012 rferrel Initial creation
* Dec 6, 2013 2561 bclement removed ECF
* Dec 20, 2013 2563 bclement fixed support for ungrouped roster items
*
* </pre>
*
@ -99,6 +101,9 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
String key = "";
if (element instanceof UserId) {
return userLabelProvider.getImage(element);
} else if (element instanceof RosterEntry) {
return userLabelProvider.getImage(IDConverter
.convertFrom((RosterEntry) element));
} else if (element instanceof RosterGroup) {
key = "group";
} else if (element instanceof IVenueSession) {
@ -178,6 +183,9 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
StringBuilder builder = new StringBuilder();
if (element instanceof UserId) {
return userLabelProvider.getToolTipText(element);
} else if (element instanceof RosterEntry) {
return userLabelProvider.getToolTipText(IDConverter
.convertFrom((RosterEntry) element));
}
// builds the tooltip text for the session group
// portion of the view

View file

@ -29,9 +29,13 @@ import org.eclipse.jface.action.IMenuCreator;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.jivesoftware.smack.RosterEntry;
import com.raytheon.uf.viz.collaboration.comm.identity.event.RosterChangeType;
import com.raytheon.uf.viz.collaboration.comm.provider.event.RosterChangeEvent;
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
import com.raytheon.uf.viz.collaboration.comm.provider.user.ContactsManager;
import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter;
import com.raytheon.uf.viz.collaboration.comm.provider.user.LocalGroups.LocalGroup;
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
import com.raytheon.uf.viz.collaboration.ui.Activator;
@ -48,6 +52,7 @@ import com.raytheon.uf.viz.core.icon.IconUtil;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jul 3, 2012 bsteffen Initial creation
* Dec 20, 2013 2563 bclement added support for ungrouped roster entries
*
* </pre>
*
@ -61,6 +66,8 @@ public class AddToGroupAction extends Action {
private final UserId[] users;
private RosterEntry entry;
/**
* This action will create a menu of groups to which the users will be added
*
@ -81,6 +88,16 @@ public class AddToGroupAction extends Action {
this.users = users;
}
/**
* Action for roster entry not currently in a group.
*
* @param entry
*/
public AddToGroupAction(RosterEntry entry) {
this(IDConverter.convertFrom(entry));
this.entry = entry;
}
@Override
public void run() {
String group = this.group;
@ -93,10 +110,17 @@ public class AddToGroupAction extends Action {
return;
}
}
CollaborationConnection connection = CollaborationConnection.getConnection();
for (UserId user : users) {
CollaborationConnection.getConnection().getContactsManager()
connection.getContactsManager()
.addToLocalGroup(group, user);
}
if (entry != null) {
// the entry wasn't in a group, so the entire tree needs to be
// refreshed
connection.postEvent(new RosterChangeEvent(RosterChangeType.MODIFY,
entry));
}
}
private class MenuCreator implements IMenuCreator {
@ -132,7 +156,9 @@ public class AddToGroupAction extends Action {
}
groups.removeAll(usedGroups);
for (LocalGroup group : groups) {
Action action = new AddToGroupAction(group.getName(), users);
AddToGroupAction action = new AddToGroupAction(group.getName(),
users);
action.setEntry(entry);
IContributionItem contrib = new ActionContributionItem(action);
contrib.fill(menu, -1);
}
@ -141,4 +167,20 @@ public class AddToGroupAction extends Action {
contrib.fill(menu, -1);
}
}
/**
* @return the entry
*/
public RosterEntry getEntry() {
return entry;
}
/**
* @param entry
* the entry to set
*/
public void setEntry(RosterEntry entry) {
this.entry = entry;
}
}

View file

@ -0,0 +1,66 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.collaboration.ui.actions;
import org.eclipse.jface.action.Action;
import org.jivesoftware.smack.RosterEntry;
import com.raytheon.uf.viz.collaboration.comm.identity.event.RosterChangeType;
import com.raytheon.uf.viz.collaboration.comm.provider.event.RosterChangeEvent;
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
import com.raytheon.uf.viz.collaboration.comm.provider.user.ContactsManager;
/**
* Action to remove entry from roster on server
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec 20, 2013 2563 bclement Initial creation
*
* </pre>
*
* @author bclement
* @version 1.0
*/
public class RemoveFromRosterAction extends Action {
private final RosterEntry entry;
public RemoveFromRosterAction(RosterEntry entry) {
super("Remove From Roster");
this.entry = entry;
}
@Override
public void run() {
CollaborationConnection connection = CollaborationConnection
.getConnection();
ContactsManager manager = connection
.getContactsManager();
manager.removeFromRoster(entry);
connection.postEvent(new RosterChangeEvent(RosterChangeType.DELETE,
entry));
}
}

View file

@ -21,15 +21,21 @@ package com.raytheon.uf.viz.collaboration.ui.data;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterGroup;
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
import com.raytheon.uf.viz.collaboration.comm.provider.session.RosterManager;
import com.raytheon.uf.viz.collaboration.comm.provider.user.LocalGroups.LocalGroup;
/**
* TODO Add Description
* Container for collaboration information window. Includes current user,
* sessions and contacts
*
* <pre>
*
@ -38,6 +44,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.LocalGroups.LocalGro
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 23, 2012 mnash Initial creation
* Dec 20, 2013 2563 bclement added items from server roster not in groups
*
* </pre>
*
@ -52,6 +59,11 @@ public class CollaborationGroupContainer {
public CollaborationGroupContainer() {
}
/**
* Get objects for UI items including current user, sessions and contacts
*
* @return
*/
public List<Object> getObjects() {
CollaborationConnection connection = CollaborationConnection
.getConnection();
@ -61,17 +73,32 @@ public class CollaborationGroupContainer {
List<Object> result = new ArrayList<Object>();
result.add(connection.getUser());
result.add(sessionGroup);
for (RosterGroup obj : connection.getRosterManager().getRoster()
.getGroups()) {
RosterManager rosterManager = connection.getRosterManager();
Roster roster = rosterManager.getRoster();
for (RosterGroup obj : roster.getGroups()) {
result.add(obj);
}
Set<String> usersInLocal = new HashSet<String>();
for (LocalGroup group : connection.getContactsManager()
.getLocalGroups()) {
usersInLocal.addAll(group.getUserNames());
result.add(group);
}
for (RosterEntry entry : roster.getUnfiledEntries()) {
// filter out entries that aren't in a group on the server, but are
// in a local group so they don't show up twice on the contacts list
if (!usersInLocal.contains(entry.getUser())) {
result.add(entry);
}
}
return result;
}
/**
* Get container for session UI objects
*
* @return
*/
public SessionGroupContainer getSessionGroup() {
return sessionGroup;
}