Issue #2701 removed local groups from collaboration

added shared groups to represent groups managed by server
local group actions changed to modify roster groups
code cleanup on contacts manager including removing unneeded roster manager
update script to clean up localization files
removed ui option to create an empty group


Former-commit-id: 26ac549096 [formerly f615f2226f [formerly 06a9db4836fa2753a913e2314a8c003380416eac]]
Former-commit-id: f615f2226f
Former-commit-id: b86ad8ca6f
This commit is contained in:
Brian Clements 2014-01-24 08:51:28 -06:00
parent 5e51b08ed3
commit fffb6aaf9a
23 changed files with 816 additions and 664 deletions

View file

@ -17,7 +17,9 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.swt,
com.raytheon.uf.common.comm,
com.raytheon.uf.common.localization,
com.raytheon.uf.viz.core
com.raytheon.uf.viz.core,
com.raytheon.uf.common.time,
com.raytheon.uf.common.util
Export-Package: com.raytheon.uf.viz.collaboration.comm,
com.raytheon.uf.viz.collaboration.comm.compression,
com.raytheon.uf.viz.collaboration.comm.identity,

View file

@ -110,6 +110,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueId;
* Jan 07, 2013 2563 bclement use getServiceName instead of getHost when creating room id
* Jan 08, 2014 2563 bclement fixed custom port and service name in user id
* Jan 15, 2014 2630 bclement connection data stores status as Mode object
* Jan 24, 2014 2701 bclement removed roster manager
*
* </pre>
*
@ -143,8 +144,6 @@ public class CollaborationConnection implements IEventPublisher {
private IAccountManager accountManager = null;
private RosterManager rosterManager = null;
private EventBus eventBus;
private ContactsManager contactsMgr;
@ -209,7 +208,7 @@ public class CollaborationConnection implements IEventPublisher {
accountManager.sendPresence(initialPresence);
}
contactsMgr = new ContactsManager(this);
contactsMgr = new ContactsManager(this, connection);
this.registerEventHandler(contactsMgr);
instanceMap.put(connectionData, this);
@ -307,28 +306,6 @@ public class CollaborationConnection implements IEventPublisher {
return accountManager;
}
/**
*
*/
private void setupRosterManager() {
if (rosterManager == null) {
if (isConnected()) {
rosterManager = new RosterManager(connection);
}
}
}
/**
*
* @return
*/
public RosterManager getRosterManager() {
if (rosterManager == null) {
setupRosterManager();
}
return rosterManager;
}
/**
* Is this SessionManager currently connected?
*

View file

@ -1,100 +0,0 @@
/**
* 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.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
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 25, 2013 2561 bclement Initial creation
* Dec 20, 2013 2563 bclement added remove from roster method
*
* </pre>
*
* @author bclement
* @version 1.0
*/
public class RosterManager {
private final XMPPConnection connection;
/**
* @param connection
*/
public RosterManager(XMPPConnection connection) {
this.connection = connection;
}
/**
* @return roster from server connection
*/
public Roster getRoster() {
return connection.getRoster();
}
/**
* Add listener for roster events
*
* @param listener
*/
public void addRosterListener(RosterListener listener) {
getRoster().addRosterListener(listener);
}
/**
* Remove listener for roster events
*
* @param listener
*/
public void removeRosterListener(RosterListener listener) {
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

@ -19,41 +19,34 @@
**/
package com.raytheon.uf.viz.collaboration.comm.provider.user;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.bind.JAXB;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.jobs.Job;
import org.apache.commons.lang.StringUtils;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterGroup;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Presence.Type;
import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smackx.SharedGroupManager;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
import com.raytheon.uf.common.localization.LocalizationFile;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.time.util.TimeUtil;
import com.raytheon.uf.common.util.collections.UpdatingSet;
import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException;
import com.raytheon.uf.viz.collaboration.comm.provider.Tools;
import com.raytheon.uf.viz.collaboration.comm.provider.event.UserNicknameChangedEvent;
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;
/**
* Manage contacts from local groups and roster on server
@ -68,6 +61,9 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.LocalGroups.LocalGro
* Dec 6, 2013 2561 bclement removed ECF
* Dec 20, 2013 2563 bclement roster items now removed from server,
* removed unneeded roster listener
* Jan 24, 2014 2701 bclement removed roster manager
* switched local groups to roster groups
* added shared groups
*
* </pre>
*
@ -79,230 +75,320 @@ public class ContactsManager {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(ContactsManager.class);
private final Job storeLocalGroupsJob = new Job("Storing Local Groups") {
@Override
protected IStatus run(IProgressMonitor monitor) {
IPathManager pm = PathManagerFactory.getPathManager();
LocalizationContext context = pm.getContext(
LocalizationType.CAVE_STATIC, LocalizationLevel.USER);
LocalizationFile file = PathManagerFactory.getPathManager()
.getLocalizationFile(
context,
"collaboration" + File.separator
+ "localGroups.xml");
LocalGroups obj;
synchronized (localGroups) {
obj = new LocalGroups(localGroups);
}
JAXB.marshal(obj, file.getFile());
try {
file.save();
} catch (LocalizationOpFailedException e) {
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
e);
}
return org.eclipse.core.runtime.Status.OK_STATUS;
}
};
private final CollaborationConnection connection;
private final XMPPConnection xmpp;
private final UserSearch search;
private List<LocalGroup> localGroups;
private Map<String, String> localAliases;
/**
* Cached view of shared groups list on openfire. Will only reach out to
* server if it hasn't updated in an hour. This will disable itself if there
* is a problem communicating with the server since the most likely case is
* that the server doesn't support the operation.
*/
private UpdatingSet<String> sharedGroups = new UpdatingSet<String>(
TimeUtil.MILLIS_PER_HOUR) {
@Override
protected Set<String> update() {
Set<String> rval;
try {
List<String> names = SharedGroupManager.getSharedGroups(xmpp);
rval = new HashSet<String>(names);
} catch (XMPPException e) {
statusHandler.warn("Unable to get shared groups."
+ " Feature may not exist on server",
e.getLocalizedMessage());
disable();
rval = null;
}
return rval;
}
};
private Set<LocalGroupListener> groupListeners = new HashSet<LocalGroupListener>();
private Set<GroupListener> groupListeners = new HashSet<GroupListener>();
public ContactsManager(CollaborationConnection connection) {
/**
* @param connection
* @param xmpp
*/
public ContactsManager(CollaborationConnection connection,
XMPPConnection xmpp) {
this.connection = connection;
this.search = connection.createSearch();
localAliases = UserIdWrapper.readAliasMap();
initLocalGroups();
this.xmpp = xmpp;
}
/**
* Get groups that are managed by server. These are not modifiable from the
* client.
*
* @return
*/
public Collection<SharedGroup> getSharedGroups() {
Set<String> groups = sharedGroups.get();
List<SharedGroup> rval = new ArrayList<SharedGroup>(groups.size());
Roster roster = getRoster();
for (String group : groups) {
RosterGroup rg = roster.getGroup(group);
rval.add(new SharedGroup(rg));
}
return rval;
}
private void initLocalGroups() {
storeLocalGroupsJob.setSystem(true);
IPathManager pm = PathManagerFactory.getPathManager();
LocalizationContext context = pm.getContext(
LocalizationType.CAVE_STATIC, LocalizationLevel.USER);
LocalizationFile file = PathManagerFactory.getPathManager()
.getLocalizationFile(context,
"collaboration" + File.separator + "localGroups.xml");
if (file.exists()) {
this.localGroups = JAXB
.unmarshal(file.getFile(), LocalGroups.class).getGroups();
}
if (this.localGroups == null) {
this.localGroups = new ArrayList<LocalGroup>();
}
for (LocalGroup group : localGroups) {
group.setManager(this);
}
}
public List<LocalGroup> getLocalGroups() {
synchronized (this.localGroups) {
return new ArrayList<LocalGroup>(this.localGroups);
}
}
public void addToLocalGroup(String groupName, UserId user) {
synchronized (this.localGroups) {
LocalGroup group = createLocalGroup(groupName);
String userId = user.getNormalizedId();
List<String> userNames = group.getUserNames();
if (!userNames.contains(userId)) {
List<UserId> users = group.getUsers();
group.getUserNames().add(userId);
users.add(user);
}
RosterEntry entry = getRosterEntry(user);
if (entry == null || entry.getGroups().isEmpty()) {
// In order to get presence for a user they must be in the
// roster, we can add them to the roster by either subscribing
// to them using presence or adding them to the roster,
// subscribing to the presence will not set the name correctly
// so we use the roster add method.
try {
RosterManager rosterManager = connection.getRosterManager();
Roster roster = rosterManager.getRoster();
roster.createEntry(userId, user.getAlias(), new String[0]);
} catch (XMPPException e) {
statusHandler.handle(Priority.PROBLEM,
e.getLocalizedMessage(), e);
/**
* Get groups that are managed by the client. This does not included shared
* groups.
*
* @return
*/
public Collection<RosterGroup> getGroups() {
Set<String> shared = sharedGroups.get();
Collection<RosterGroup> groups = getRoster().getGroups();
Collection<RosterGroup> rval;
if (shared.isEmpty()) {
rval = groups;
} else {
rval = new ArrayList<RosterGroup>(groups.size());
for (RosterGroup group : groups) {
if (!shared.contains(group.getName())) {
rval.add(group);
}
}
for (LocalGroupListener listener : getSafeGroupListeners()) {
}
return rval;
}
/**
* Add user to group. Creates group if it doesn't exist. Adds user to
* contacts if not in roster.
*
* @param groupName
* @param user
*/
public void addToGroup(String groupName, UserId user) {
Roster roster = getRoster();
RosterGroup group = roster.getGroup(groupName);
if (group == null) {
group = createGroup(groupName);
}
String id = user.getNormalizedId();
RosterEntry entry = group.getEntry(id);
if (entry != null) {
statusHandler
.debug("Attempted to add user to group it was already in: "
+ id + " in " + groupName);
return;
}
try {
addToGroup(group, user);
for (GroupListener listener : getSafeGroupListeners()) {
listener.userAdded(group, user);
}
} catch (XMPPException e) {
String msg = getGroupModInfo(e);
statusHandler.error("Problem adding user to group: " + id + " to "
+ group.getName() + ". " + msg, e);
}
storeLocalGroupsJob.schedule();
}
public void deleteFromLocalGroup(String groupName, UserId user) {
synchronized (localGroups) {
Iterator<LocalGroup> it = localGroups.iterator();
while (it.hasNext()) {
LocalGroup group = it.next();
if (group.getName().equals(groupName)) {
group.getUsers().remove(user);
group.getUserNames().remove(user.getNormalizedId());
for (LocalGroupListener listener : getSafeGroupListeners()) {
listener.userDeleted(group, user);
}
break;
}
/**
* Add user to group. Adds user to contacts if not in roster.
*
* @param group
* @param user
* @throws XMPPException
*/
private void addToGroup(RosterGroup group, UserId user)
throws XMPPException {
RosterEntry entry = getRosterEntry(user);
if (entry == null) {
// we dont have user as a contact at all
// ensure that the user object is up-to-date
user = findUser(user.getName());
String alias = user.getAlias();
if (StringUtils.isBlank(alias)) {
alias = user.getName();
}
if (getLocalGroups(user).isEmpty()) {
// if the user is in no local groups and no roster groups remove
// them from our roster.
RosterEntry entry = getRosterEntry(user);
if (entry != null && entry.getGroups().isEmpty()) {
Presence presence = new Presence(Type.unsubscribe);
presence.setTo(user.getNormalizedId());
try {
connection.getAccountManager().sendPresence(presence);
} catch (CollaborationException e) {
statusHandler.error(
"Problem removing user from roster", e);
}
removeFromRoster(entry);
}
}
storeLocalGroupsJob.schedule();
getRoster().createEntry(user.getFQName(), alias,
new String[] { group.getName() });
} else {
// just need to update groups
group.addEntry(entry);
}
}
/**
* Remove user from group.
*
* @param groupName
* @param user
*/
public void deleteFromGroup(String groupName, UserId user) {
RosterEntry entry = getRosterEntry(user);
if ( entry == null){
statusHandler.warn("Attempted to alter group for non-contact: " + user);
return;
}
RosterGroup group = getRoster().getGroup(groupName);
if ( group != null){
deleteFromGroup(group, entry);
} else {
statusHandler.warn("Attempted to modify non-existent group: "
+ groupName);
}
}
/**
* Remove entry from group.
*
* @param group
* @param entry
*/
private void deleteFromGroup(RosterGroup group, RosterEntry entry) {
try {
group.removeEntry(entry);
for (GroupListener listener : getSafeGroupListeners()) {
listener.userDeleted(group, IDConverter.convertFrom(entry));
}
} catch (XMPPException e) {
String msg = getGroupModInfo(e);
statusHandler.error("Problem removing entry from group: "
+ IDConverter.convertFrom(entry) + " from "
+ group.getName() + ". " + msg, e);
}
}
/**
* Attempt to get more information about group modification error. Returns
* an empty string if no extra information is found.
*
* @param e
* @return
*/
private String getGroupModInfo(XMPPException e) {
XMPPError xmppError = e.getXMPPError();
String rval = "";
if (xmppError != null) {
switch (xmppError.getCode()) {
case 406:
rval = "Group may not be modifiable. ";
break;
}
}
return rval;
}
/**
* Remove entry from roster on server
*
* @param entry
* @throws CollaborationException
*/
public void removeFromRoster(RosterEntry entry) {
RosterManager rosterManager = connection.getRosterManager();
Roster roster = getRoster();
try {
rosterManager.removeFromRoster(entry);
} catch (CollaborationException e) {
roster.removeEntry(entry);
} catch (XMPPException e) {
statusHandler.error("Problem removing roster entry", e);
}
}
public LocalGroup createLocalGroup(String groupName) {
synchronized (localGroups) {
for (LocalGroup group : this.localGroups) {
if (groupName.equals(group.getName())) {
return group;
}
}
LocalGroup group = new LocalGroup(groupName);
group.setManager(this);
localGroups.add(group);
for (LocalGroupListener listener : getSafeGroupListeners()) {
/**
* Create group. At least one entry must be placed into group for it to be
* persisted on server.
*
* @param groupName
* @return
*/
public RosterGroup createGroup(String groupName) {
Roster roster = getRoster();
RosterGroup rval = roster.getGroup(groupName);
if ( rval != null){
statusHandler.debug("Attempted to create existing group: " + groupName);
return rval;
}
rval = roster.createGroup(groupName);
for (GroupListener listener : getSafeGroupListeners()) {
listener.groupCreated(rval);
}
return rval;
}
/**
* Remove all users from group.
*
* @param groupName
*/
public void deleteGroup(String groupName) {
Roster roster = getRoster();
RosterGroup group = roster.getGroup(groupName);
if ( group == null){
statusHandler.warn("Attempted to delete non-existent group: "
+ groupName);
return;
}
Collection<RosterEntry> entries = group.getEntries();
for (RosterEntry entry : entries) {
deleteFromGroup(group, entry);
}
for (GroupListener listener : getSafeGroupListeners()) {
listener.groupDeleted(group);
}
}
/**
* Move all users from old group to new group. If new group already exists,
* this will merge the two groups.
*
* @param oldName
* @param newName
*/
public void renameGroup(String oldName, String newName) {
Roster roster = getRoster();
RosterGroup group = roster.getGroup(oldName);
if (group == null) {
statusHandler.warn("Attempted to rename non-existent group: "
+ oldName);
return;
}
boolean merger = roster.getGroup(newName) != null;
group.setName(newName);
for (GroupListener listener : getSafeGroupListeners()) {
listener.groupDeleted(group);
}
if (!merger) {
for (GroupListener listener : getSafeGroupListeners()) {
listener.groupCreated(group);
}
storeLocalGroupsJob.schedule();
return group;
}
}
public void deleteLocalGroup(String groupName) {
synchronized (localGroups) {
Iterator<LocalGroup> it = this.localGroups.iterator();
while (it.hasNext()) {
LocalGroup group = it.next();
if (groupName.equals(group.getName())) {
List<UserId> users = new ArrayList<UserId>(
group.getUsers());
for (UserId user : users) {
deleteFromLocalGroup(groupName, user);
}
it.remove();
for (LocalGroupListener listener : getSafeGroupListeners()) {
listener.groupDeleted(group);
}
}
}
/**
* Get groups that the user is in.
*
* @param user
* @return
*/
public Collection<RosterGroup> getGroups(UserId user) {
RosterEntry entry = getRoster().getEntry(user.getNormalizedId());
if (entry == null) {
statusHandler.error("Requested groups for user not in roster: "
+ user);
return Collections.emptyList();
}
storeLocalGroupsJob.schedule();
}
public void renameLocalGroup(String oldName, String newName) {
synchronized (localGroups) {
for (LocalGroup group : localGroups) {
if (oldName.equals(group.getName())) {
for (LocalGroupListener listener : getSafeGroupListeners()) {
listener.groupDeleted(group);
}
group.setName(newName);
for (LocalGroupListener listener : getSafeGroupListeners()) {
listener.groupCreated(group);
}
}
}
}
storeLocalGroupsJob.schedule();
}
public List<LocalGroup> getLocalGroups(UserId user) {
List<LocalGroup> results = new ArrayList<LocalGroup>();
synchronized (localGroups) {
for (LocalGroup group : localGroups) {
for (String userName : group.getUserNames()) {
if (user.getNormalizedId().equals(userName)) {
results.add(group);
break;
}
}
}
}
return results;
return entry.getGroups();
}
/**
* Update local alias for user. Does not persist to server.
*
* @param user
* @param nickname
*/
public void setNickname(UserId user, String nickname) {
synchronized (localAliases) {
@ -348,18 +434,36 @@ public class ContactsManager {
return alias;
}
/**
* Get user info from roster. Does not include local alias information.
*
* @param userId
* @return
*/
public UserId getUser(String userId) {
RosterEntry entry = searchRoster(getRoster(), userId);
RosterEntry entry = searchRoster(userId);
if (entry == null) {
return null;
}
return IDConverter.convertFrom(entry);
}
/**
* Get entry from roster for user. Does not include local alias information.
*
* @param user
* @return
*/
public RosterEntry getRosterEntry(UserId user) {
return searchRoster(user);
return searchRoster(user.getNormalizedId());
}
/**
* Get last known presence for contact.
*
* @param user
* @return
*/
public Presence getPresence(UserId user) {
UserId self = connection.getUser();
if (self.isSameUser(user)) {
@ -369,54 +473,35 @@ public class ContactsManager {
return roster.getPresence(user.getNormalizedId());
}
/**
* Get presence for this account.
*
* @return
*/
public Presence getSelfPresence() {
return connection.getPresence();
}
/**
* Used by local groups to make sure all local group items are in the
* roster.
* Convenience method for accessing roster.
*
* @param name
* @return
*/
protected UserId findAndAddUser(String id) {
UserId user = null;
RosterEntry entry = searchRoster(getRoster(), id);
if (entry != null) {
user = IDConverter.convertFrom(entry);
}
if (user == null) {
user = findUser(id);
if (user != null) {
try {
Roster roster = connection.getRosterManager().getRoster();
String alias = user.getAlias();
if (alias == null || alias.trim().isEmpty()) {
alias = user.getName();
}
roster.createEntry(user.getFQName(), alias, new String[0]);
} catch (XMPPException e) {
statusHandler.handle(Priority.PROBLEM,
e.getLocalizedMessage(), e);
}
}
}
return user;
}
/**
* @return
*/
private Roster getRoster() {
return connection.getRosterManager().getRoster();
return xmpp.getRoster();
}
private UserId findUser(String idString) {
/**
* Perform an XMPP search for user. Includes any local alias information.
*
* @param username
* The part of the userid before the '@'
* @return null if not found
*/
private UserId findUser(String username) {
List<UserId> results;
try {
results = search.byId(idString);
results = search.byUsername(username);
} catch (XMPPException e) {
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
return null;
@ -431,44 +516,72 @@ public class ContactsManager {
return results.isEmpty() ? null : results.iterator().next();
}
private RosterEntry searchRoster(UserId user) {
String userId = user.getNormalizedId();
return searchRoster(connection.getRosterManager().getRoster(), userId);
/**
* Get entry from roster for user. Does not include local alias information.
*
* @param userId
* @return
*/
private RosterEntry searchRoster(String userId) {
return getRoster().getEntry(userId);
}
private RosterEntry searchRoster(Roster roster, String userId) {
return roster.getEntry(userId);
}
public void addLocalGroupListener(LocalGroupListener listener) {
/**
* Add listeners to get information on when groups are modified
*
* @param listener
*/
public void addGroupListener(GroupListener listener) {
synchronized (groupListeners) {
groupListeners.add(listener);
}
}
public void removeLocalGroupListener(LocalGroupListener listener) {
/**
* Remove listener
*
* @param listener
*/
public void removeGroupListener(GroupListener listener) {
synchronized (groupListeners) {
groupListeners.remove(listener);
}
}
protected Set<LocalGroupListener> getSafeGroupListeners() {
Set<LocalGroupListener> safeSet = new HashSet<LocalGroupListener>();
/**
* Get a copy of the listeners set
*
* @return
*/
protected Set<GroupListener> getSafeGroupListeners() {
Set<GroupListener> safeSet = new HashSet<GroupListener>();
synchronized (groupListeners) {
safeSet.addAll(groupListeners);
}
return safeSet;
}
public static interface LocalGroupListener {
/**
* Get a list of roster entries that do not belong to any group
*
* @return
*/
public Collection<RosterEntry> getNonGroupedContacts() {
return getRoster().getUnfiledEntries();
}
public void groupCreated(LocalGroup group);
/**
* Listener interface for group update events
*/
public static interface GroupListener {
public void groupDeleted(LocalGroup group);
public void groupCreated(RosterGroup group);
public void userAdded(LocalGroup group, UserId user);
public void groupDeleted(RosterGroup group);
public void userDeleted(LocalGroup group, UserId user);
public void userAdded(RosterGroup group, UserId user);
public void userDeleted(RosterGroup group, UserId user);
}
}

View file

@ -1,131 +0,0 @@
/**
* 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.comm.provider.user;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
/**
* Group information not stored on chat server
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jul 2, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name = "LocalGroups")
public class LocalGroups {
@XmlElement(name = "group")
private List<LocalGroup> groups;
public LocalGroups() {
}
public LocalGroups(List<LocalGroup> groups) {
this.groups = new ArrayList<LocalGroup>(groups);
}
public List<LocalGroup> getGroups() {
return groups;
}
public void setGroups(List<LocalGroup> groups) {
this.groups = groups;
}
@XmlAccessorType(XmlAccessType.NONE)
public static class LocalGroup {
@XmlAttribute
private String name;
@XmlElement(name = "user")
private List<String> userNames;
@XmlTransient
private ContactsManager manager;
@XmlTransient
private List<UserId> users;
public LocalGroup() {
}
public LocalGroup(String name) {
this.name = name;
this.userNames = new ArrayList<String>();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getUserNames() {
if (userNames == null) {
userNames = new ArrayList<String>();
}
return userNames;
}
public void setUserNames(List<String> userNames) {
this.userNames = userNames;
}
public synchronized List<UserId> getUsers() {
if (users == null) {
users = new ArrayList<UserId>();
for (String userName : userNames) {
UserId user = manager.findAndAddUser(userName);
if (user != null) {
users.add(user);
}
}
}
return users;
}
public void setManager(ContactsManager manager) {
this.manager = manager;
}
}
}

View file

@ -0,0 +1,76 @@
/**
* 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.comm.provider.user;
import java.util.Collection;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterGroup;
/**
* Shared group managed by xmpp server. Cannot be modified by client.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 23, 2014 2701 bclement Initial creation
*
* </pre>
*
* @author bclement
* @version 1.0
*/
public class SharedGroup {
private final RosterGroup delegate;
/**
* @param group
*/
public SharedGroup(RosterGroup group) {
this.delegate = group;
}
/**
* @return name of group
*/
public String getName() {
return delegate.getName();
}
/**
* @return collection of entries in this group
*/
public Collection<RosterEntry> getEntries() {
return delegate.getEntries();
}
/**
* @param entry
* @return true if entry is in this group
*/
public boolean contains(RosterEntry entry) {
return delegate.contains(entry);
}
}

View file

@ -46,6 +46,7 @@ import com.raytheon.uf.common.status.UFStatus;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 22, 2013 2561 bclement Initial creation
* Jan 24, 2014 2701 bclement distinction between userid and username
*
* </pre>
*
@ -62,7 +63,7 @@ public class UserSearch {
private static final String SEARCH_ACTION = "search";
public static final String USERID_FIELD = "Username";
public static final String USERNAME_FIELD = "Username";
public static final String JABBER_ID_COLUMN = "jid";
@ -81,14 +82,14 @@ public class UserSearch {
}
/**
* Search by username
* Search by username (the part of the user id before the @)
*
* @param name
* @return list of user ids that match that name
* @throws XMPPException
*/
public List<UserId> byId(String id) throws XMPPException {
return byCriteria(USERID_FIELD, id);
public List<UserId> byUsername(String username) throws XMPPException {
return byCriteria(USERNAME_FIELD, username);
}
/**

View file

Before

Width:  |  Height:  |  Size: 376 B

After

Width:  |  Height:  |  Size: 376 B

View file

Before

Width:  |  Height:  |  Size: 605 B

After

Width:  |  Height:  |  Size: 605 B

View file

@ -21,6 +21,7 @@ package com.raytheon.uf.viz.collaboration.ui;
**/
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
@ -88,9 +89,9 @@ import com.raytheon.uf.viz.collaboration.comm.provider.event.UserNicknameChanged
import com.raytheon.uf.viz.collaboration.comm.provider.event.UserPresenceChangedEvent;
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.ContactsManager.LocalGroupListener;
import com.raytheon.uf.viz.collaboration.comm.provider.user.ContactsManager.GroupListener;
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.SharedGroup;
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
import com.raytheon.uf.viz.collaboration.ui.actions.AddToGroupAction;
import com.raytheon.uf.viz.collaboration.ui.actions.ArchiveViewerAction;
@ -100,7 +101,6 @@ import com.raytheon.uf.viz.collaboration.ui.actions.ChangeRoleAction;
import com.raytheon.uf.viz.collaboration.ui.actions.ChangeSiteAction;
import com.raytheon.uf.viz.collaboration.ui.actions.ChangeStatusAction;
import com.raytheon.uf.viz.collaboration.ui.actions.ChangeStatusMessageAction;
import com.raytheon.uf.viz.collaboration.ui.actions.CreateGroupAction;
import com.raytheon.uf.viz.collaboration.ui.actions.CreateSessionAction;
import com.raytheon.uf.viz.collaboration.ui.actions.DeleteGroupAction;
import com.raytheon.uf.viz.collaboration.ui.actions.DisplayFeedAction;
@ -136,6 +136,8 @@ import com.raytheon.viz.ui.views.CaveFloatingView;
* 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
* Jan 24, 2014 2701 bclement removed local groups, added shared groups
* removed option to create empty group
*
* </pre>
*
@ -143,7 +145,7 @@ import com.raytheon.viz.ui.views.CaveFloatingView;
* @version 1.0
*/
public class CollaborationGroupView extends CaveFloatingView implements
LocalGroupListener, IUserSelector {
GroupListener, IUserSelector {
public static final String ID = "com.raytheon.uf.viz.collaboration.ui.CollaborationGroupView";
private TreeViewer usersTreeViewer;
@ -228,7 +230,7 @@ public class CollaborationGroupView extends CaveFloatingView implements
if (connection != null) {
connection.registerEventHandler(this);
}
connection.getContactsManager().addLocalGroupListener(this);
connection.getContactsManager().addGroupListener(this);
populateTree();
usersTreeViewer.refresh();
parent.layout();
@ -240,7 +242,7 @@ public class CollaborationGroupView extends CaveFloatingView implements
.getConnection();
if (connection != null) {
connection.unregisterEventHandler(this);
connection.getContactsManager().removeLocalGroupListener(this);
connection.getContactsManager().removeGroupListener(this);
}
super.dispose();
@ -311,7 +313,6 @@ public class CollaborationGroupView extends CaveFloatingView implements
}
private void createMenu(IMenuManager mgr) {
mgr.add(new CreateGroupAction());
mgr.add(new UserSearchAction());
mgr.add(new Separator());
mgr.add(new ChangeFontAction());
@ -402,10 +403,10 @@ public class CollaborationGroupView extends CaveFloatingView implements
// 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) {
} else if (o instanceof RosterGroup || o instanceof SharedGroup) {
manager.add(createSessionAction);
if (o instanceof LocalGroup) {
LocalGroup group = (LocalGroup) o;
if (o instanceof RosterGroup) {
RosterGroup group = (RosterGroup) o;
manager.add(new DeleteGroupAction(group.getName()));
aliasAction.setId(group.getName());
aliasAction.setText("Rename Group");
@ -438,8 +439,8 @@ public class CollaborationGroupView extends CaveFloatingView implements
manager.add(new AddToGroupAction(getSelectedUsers()));
String groupName = null;
Object group = selection.getPaths()[0].getFirstSegment();
if (group instanceof LocalGroup) {
groupName = ((LocalGroup) group).getName();
if (group instanceof RosterGroup) {
groupName = ((RosterGroup) group).getName();
manager.add(new RemoveFromGroupAction(groupName, getSelectedUsers()));
}
}
@ -587,14 +588,14 @@ public class CollaborationGroupView extends CaveFloatingView implements
CollaborationConnection.getConnection().getContactsManager()
.setNickname(user, newText);
CollaborationConnection.getConnection().postEvent(user);
for (LocalGroup group : CollaborationConnection.getConnection()
.getContactsManager().getLocalGroups(user)) {
for (RosterGroup group : CollaborationConnection.getConnection()
.getContactsManager().getGroups(user)) {
usersTreeViewer.refresh(group);
}
} else if (selectedObj instanceof LocalGroup) {
LocalGroup group = (LocalGroup) selectedObj;
} else if (selectedObj instanceof RosterGroup) {
RosterGroup group = (RosterGroup) selectedObj;
CollaborationConnection.getConnection().getContactsManager()
.renameLocalGroup(group.getName(), newText);
.renameGroup(group.getName(), newText);
}
}
@ -790,16 +791,13 @@ public class CollaborationGroupView extends CaveFloatingView implements
UserId user = IDConverter.convertFrom((RosterEntry) node);
selectedUsers.add(user);
} else if (node instanceof RosterGroup) {
selectedUsers.addAll(getSelectedUsers((RosterGroup) node));
} else if (node instanceof LocalGroup) {
for (UserId user : ((LocalGroup) node).getUsers()) {
Presence presence = CollaborationConnection
.getConnection().getContactsManager()
.getPresence(user);
if (presence.getType() == Presence.Type.available) {
selectedUsers.add(user);
}
}
Collection<RosterEntry> entries = ((RosterGroup) node)
.getEntries();
selectedUsers.addAll(getSelectedUsers(entries));
} else if (node instanceof SharedGroup) {
Collection<RosterEntry> entries = ((SharedGroup) node)
.getEntries();
selectedUsers.addAll(getSelectedUsers(entries));
}
}
@ -807,17 +805,16 @@ public class CollaborationGroupView extends CaveFloatingView implements
}
/**
* This recursively searches group Nodes and returns all users with Type
* AVAILABLE.
* This searches group entries and returns all users with Type AVAILABLE.
*
* @param groupNode
* @param entries
* @return users
*/
private Set<UserId> getSelectedUsers(RosterGroup groupNode) {
private Set<UserId> getSelectedUsers(Collection<RosterEntry> entries) {
Set<UserId> selectedUsers = new HashSet<UserId>();
ContactsManager contacts = CollaborationConnection.getConnection()
.getContactsManager();
for (RosterEntry node : groupNode.getEntries()) {
for (RosterEntry node : entries) {
UserId user = IDConverter.convertFrom(node);
Presence presence = contacts.getPresence(user);
if (presence.getType() == Type.available) {
@ -902,22 +899,22 @@ public class CollaborationGroupView extends CaveFloatingView implements
}
@Override
public void groupCreated(LocalGroup group) {
public void groupCreated(RosterGroup group) {
refreshUsersTreeViewerAsync(usersTreeViewer.getInput());
}
@Override
public void groupDeleted(LocalGroup group) {
public void groupDeleted(RosterGroup group) {
refreshUsersTreeViewerAsync(usersTreeViewer.getInput());
}
@Override
public void userAdded(LocalGroup group, UserId user) {
public void userAdded(RosterGroup group, UserId user) {
refreshUsersTreeViewerAsync(group);
}
@Override
public void userDeleted(LocalGroup group, UserId user) {
public void userDeleted(RosterGroup group, UserId user) {
refreshUsersTreeViewerAsync(group);
}

View file

@ -37,7 +37,8 @@ import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConn
import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
/**
* TODO Add Description
* Dialog allowing user to create a new group in the roster. At least one user
* must be added to the group afterwards for it to be persisted on the server.
*
* <pre>
*
@ -46,13 +47,13 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 27, 2012 bsteffen Initial creation
* Jan 24, 2014 2701 bclement removed local groups
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class CreateGroupDialog extends CaveSWTDialog {
private Text nameText;
@ -115,7 +116,7 @@ public class CreateGroupDialog extends CaveSWTDialog {
private void finish() {
newGroup = nameText.getText();
CollaborationConnection.getConnection().getContactsManager()
.createLocalGroup(newGroup);
.createGroup(newGroup);
close();
}

View file

@ -33,13 +33,13 @@ import org.jivesoftware.smack.RosterGroup;
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.SharedGroup;
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
import com.raytheon.uf.viz.collaboration.ui.data.CollaborationGroupContainer;
import com.raytheon.uf.viz.collaboration.ui.data.SessionGroupContainer;
/**
* TODO Add Description
* Provides access to contacts list tree
*
* <pre>
*
@ -49,6 +49,7 @@ import com.raytheon.uf.viz.collaboration.ui.data.SessionGroupContainer;
* ------------ ---------- ----------- --------------------------
* Mar 1, 2012 rferrel Initial creation
* Dec 6, 2013 2561 bclement removed ECF
* Jan 24, 2014 2701 bclement removed local groups, added shared groups
*
* </pre>
*
@ -118,35 +119,33 @@ public class UsersTreeContentProvider implements ITreeContentProvider {
return cont.getObjects().toArray();
} else if (parentElement instanceof RosterGroup) {
RosterGroup group = (RosterGroup) parentElement;
List<UserId> result = new ArrayList<UserId>();
UserId localUser = CollaborationConnection.getConnection()
.getUser();
Collection<RosterEntry> entries = group.getEntries();
synchronized (entries) {
entries = new ArrayList<RosterEntry>(entries);
}
for (RosterEntry entry : entries) {
String user = entry.getUser();
if (!localUser.isSameUser(user)) {
result.add(IDConverter.convertFrom(entry));
}
}
return result.toArray();
} else if (parentElement instanceof LocalGroup) {
List<UserId> result = new ArrayList<UserId>();
LocalGroup group = (LocalGroup) parentElement;
UserId localUser = CollaborationConnection.getConnection()
.getUser();
for (UserId user : group.getUsers()) {
if (!localUser.isSameUser(user.getNormalizedId())) {
result.add(user);
}
}
return result.toArray();
return getRosterChildren(group.getEntries());
} else if (parentElement instanceof SharedGroup) {
SharedGroup group = (SharedGroup) parentElement;
return getRosterChildren(group.getEntries());
}
return null;
}
/**
* Get child objects of roster groups
*
* @param entries
* entries in group
* @return
*/
private Object[] getRosterChildren(Collection<RosterEntry> entries) {
List<UserId> result = new ArrayList<UserId>();
UserId localUser = CollaborationConnection.getConnection().getUser();
for (RosterEntry entry : entries) {
String user = entry.getUser();
if (!localUser.isSameUser(user)) {
result.add(IDConverter.convertFrom(entry));
}
}
return result.toArray();
}
/*
* (non-Javadoc)
*
@ -172,19 +171,10 @@ public class UsersTreeContentProvider implements ITreeContentProvider {
boolean hasChildren = false;
if (element instanceof RosterGroup) {
RosterGroup group = (RosterGroup) element;
UserId localUser = CollaborationConnection.getConnection()
.getUser();
Collection<RosterEntry> entries = group.getEntries();
synchronized (entries) {
entries = new ArrayList<RosterEntry>(entries);
}
for (RosterEntry entry : entries) {
String user = entry.getUser();
if (!localUser.isSameUser(user)) {
hasChildren = true;
break;
}
}
hasChildren = rosterHasChildren(group.getEntries());
} else if (element instanceof SharedGroup) {
SharedGroup group = (SharedGroup) element;
hasChildren = rosterHasChildren(group.getEntries());
} else if (element instanceof SessionGroupContainer) {
SessionGroupContainer cont = (SessionGroupContainer) element;
if (cont.getObjects() != null && cont.getObjects().size() > 0) {
@ -192,16 +182,6 @@ public class UsersTreeContentProvider implements ITreeContentProvider {
} else {
hasChildren = false;
}
} else if (element instanceof LocalGroup) {
UserId localUser = CollaborationConnection.getConnection()
.getUser();
List<String> userNames = ((LocalGroup) element).getUserNames();
for (String userName : userNames) {
if (!localUser.isSameUser(userName)) {
hasChildren = true;
break;
}
}
}
// need to check whether items are filtered out so we don't get
@ -219,4 +199,22 @@ public class UsersTreeContentProvider implements ITreeContentProvider {
}
return hasChildren;
}
/**
* @param entries
* @return true if entries has at least one entry that isn't the users
* account
*/
private boolean rosterHasChildren(Collection<RosterEntry> entries) {
UserId localUser = CollaborationConnection.getConnection().getUser();
boolean hasChildren = false;
for (RosterEntry entry : entries) {
String user = entry.getUser();
if (!localUser.isSameUser(user)) {
hasChildren = true;
break;
}
}
return hasChildren;
}
}

View file

@ -43,7 +43,7 @@ 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.SharedGroup;
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
import com.raytheon.uf.viz.collaboration.ui.data.SessionGroupContainer;
@ -59,6 +59,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
* Jan 24, 2014 2701 bclement removed local groups, added shared groups
*
* </pre>
*
@ -105,13 +106,13 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
return userLabelProvider.getImage(IDConverter
.convertFrom((RosterEntry) element));
} else if (element instanceof RosterGroup) {
key = "group";
key = "roster_group";
} else if (element instanceof SharedGroup) {
key = "shared_group";
} else if (element instanceof IVenueSession) {
// key = "session_group";
} else if (element instanceof SessionGroupContainer) {
key = "session_group";
} else if (element instanceof LocalGroup) {
key = "local_group";
}
if (imageMap.get(key) == null && !key.equals("")) {
@ -124,6 +125,8 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
public String getText(Object element) {
if (element instanceof RosterGroup) {
return ((RosterGroup) element).getName();
} else if (element instanceof SharedGroup) {
return ((SharedGroup) element).getName();
} else if (element instanceof RosterEntry) {
return userLabelProvider.getText(IDConverter
.convertFrom((RosterEntry) element));
@ -153,17 +156,14 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
return null;
}
return info.getVenueDescription();
} else if (element instanceof LocalGroup) {
return ((LocalGroup) element).getName();
}
return null;
}
@Override
public Font getFont(Object element) {
if (element instanceof RosterGroup
|| element instanceof SessionGroupContainer
|| element instanceof LocalGroup) {
if (element instanceof RosterGroup || element instanceof SharedGroup
|| element instanceof SessionGroupContainer) {
// for this case do nothing, as it is not the top level of
// session groups
if (boldFont == null) {

View file

@ -26,12 +26,12 @@ import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterGroup;
import com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession;
import com.raytheon.uf.viz.collaboration.comm.provider.user.LocalGroups.LocalGroup;
import com.raytheon.uf.viz.collaboration.comm.provider.user.SharedGroup;
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
import com.raytheon.uf.viz.collaboration.ui.data.SessionGroupContainer;
/**
* TODO Add Description
* Sorts the contacts list
*
* <pre>
*
@ -41,6 +41,7 @@ import com.raytheon.uf.viz.collaboration.ui.data.SessionGroupContainer;
* ------------ ---------- ----------- --------------------------
* Mar 1, 2012 rferrel Initial creation
* Dec 6, 2013 2561 bclement removed ECF
* Jan 24, 2014 2701 bclement removed local groups, added shared groups
*
* </pre>
*
@ -74,9 +75,12 @@ public class UsersTreeViewerSorter extends ViewerSorter {
}
// Groups before users.
if (e1 instanceof RosterGroup) {
if (!(e2 instanceof RosterGroup)) {
if (e1 instanceof SharedGroup) {
if (!(e2 instanceof SharedGroup)) {
return -1;
} else {
return ((SharedGroup) e1).getName().compareTo(
((SharedGroup) e2).getName());
}
} else if (e1 instanceof RosterGroup) {
return 1;
@ -113,17 +117,18 @@ public class UsersTreeViewerSorter extends ViewerSorter {
return ((IVenueSession) e1).getVenue().toString()
.compareTo(((IVenueSession) e2).getVenue().toString());
}
if (e1 instanceof LocalGroup) {
if (!(e2 instanceof LocalGroup)) {
if (e1 instanceof RosterGroup) {
if (!(e2 instanceof RosterGroup)) {
return -1;
}
} else if (e1 instanceof LocalGroup) {
} else if (e1 instanceof RosterGroup) {
return 1;
}
if (e1 instanceof LocalGroup && e2 instanceof LocalGroup) {
return ((LocalGroup) e1).getName().compareTo(
((LocalGroup) e2).getName());
if (e1 instanceof RosterGroup && e2 instanceof RosterGroup) {
return ((RosterGroup) e1).getName().compareTo(
((RosterGroup) e2).getName());
}
return 0;
}
}

View file

@ -19,9 +19,6 @@
**/
package com.raytheon.uf.viz.collaboration.ui.actions;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IContributionItem;
@ -30,13 +27,13 @@ import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterGroup;
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;
import com.raytheon.uf.viz.collaboration.ui.CreateGroupDialog;
@ -53,13 +50,13 @@ import com.raytheon.uf.viz.core.icon.IconUtil;
* ------------ ---------- ----------- --------------------------
* Jul 3, 2012 bsteffen Initial creation
* Dec 20, 2013 2563 bclement added support for ungrouped roster entries
* Jan 24, 2014 2701 bclement removed local groups
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class AddToGroupAction extends Action {
private final String group;
@ -83,7 +80,7 @@ public class AddToGroupAction extends Action {
public AddToGroupAction(String group, UserId... users) {
super(group, IconUtil.getImageDescriptor(Activator.getDefault()
.getBundle(), "local_group.gif"));
.getBundle(), "roster_group.gif"));
this.group = group;
this.users = users;
}
@ -112,8 +109,7 @@ public class AddToGroupAction extends Action {
}
CollaborationConnection connection = CollaborationConnection.getConnection();
for (UserId user : users) {
connection.getContactsManager()
.addToLocalGroup(group, user);
connection.getContactsManager().addToGroup(group, user);
}
if (entry != null) {
// the entry wasn't in a group, so the entire tree needs to be
@ -149,13 +145,7 @@ public class AddToGroupAction extends Action {
private void fill() {
ContactsManager contactsMgr = CollaborationConnection
.getConnection().getContactsManager();
List<LocalGroup> groups = contactsMgr.getLocalGroups();
List<LocalGroup> usedGroups = new ArrayList<LocalGroup>(groups);
for (UserId user : users) {
usedGroups.retainAll(contactsMgr.getLocalGroups(user));
}
groups.removeAll(usedGroups);
for (LocalGroup group : groups) {
for (RosterGroup group : contactsMgr.getGroups()) {
AddToGroupAction action = new AddToGroupAction(group.getName(),
users);
action.setEntry(entry);

View file

@ -39,6 +39,7 @@ import com.raytheon.uf.viz.core.icon.IconUtil;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jul 3, 2012 bsteffen Initial creation
* Jan 24, 2014 2701 bclement removed local groups
*
* </pre>
*
@ -74,7 +75,7 @@ public class CreateGroupAction extends Action {
}
for (UserId user : users) {
CollaborationConnection.getConnection().getContactsManager()
.addToLocalGroup(group, user);
.addToGroup(group, user);
}
}
}

View file

@ -35,6 +35,7 @@ import com.raytheon.uf.viz.core.icon.IconUtil;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jul 3, 2012 bsteffen Initial creation
* Jan 24, 2014 2701 bclement removed local groups
*
* </pre>
*
@ -55,6 +56,6 @@ public class DeleteGroupAction extends Action {
@Override
public void run() {
CollaborationConnection.getConnection().getContactsManager()
.deleteLocalGroup(group);
.deleteGroup(group);
}
}

View file

@ -37,6 +37,7 @@ import com.raytheon.uf.viz.core.icon.IconUtil;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jul 3, 2012 bsteffen Initial creation
* Jan 24, 2014 2701 bclement removed local groups
*
* </pre>
*
@ -62,7 +63,7 @@ public class RemoveFromGroupAction extends Action {
ContactsManager manager = CollaborationConnection.getConnection()
.getContactsManager();
for (UserId user : users) {
manager.deleteFromLocalGroup(group, user);
manager.deleteFromGroup(group, user);
}
}
}

View file

@ -21,17 +21,10 @@ 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;
import com.raytheon.uf.viz.collaboration.comm.provider.user.ContactsManager;
/**
* Container for collaboration information window. Includes current user,
@ -45,6 +38,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.LocalGroups.LocalGro
* ------------ ---------- ----------- --------------------------
* Apr 23, 2012 mnash Initial creation
* Dec 20, 2013 2563 bclement added items from server roster not in groups
* Jan 24, 2014 2701 bclement removed local groups, added shared groups
*
* </pre>
*
@ -73,24 +67,10 @@ public class CollaborationGroupContainer {
List<Object> result = new ArrayList<Object>();
result.add(connection.getUser());
result.add(sessionGroup);
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);
}
}
ContactsManager contactsManager = connection.getContactsManager();
result.addAll(contactsManager.getSharedGroups());
result.addAll(contactsManager.getGroups());
result.addAll(contactsManager.getNonGroupedContacts());
return result;
}

View file

@ -0,0 +1,9 @@
#!/bin/bash
echo "INFO: update started - removing collaboration local groups localization files"
find /awips2/edex/data/utility -type f -regex '.*collaboration/localGroups.xml$' -exec rm -vf {} \;
echo "INFO: the update has completed successfully!"
exit 0

View file

@ -12,6 +12,7 @@ Require-Bundle: org.apache.commons.beanutils;bundle-version="1.8.3",
Export-Package: com.raytheon.uf.common.util,
com.raytheon.uf.common.util.algorithm,
com.raytheon.uf.common.util.cache,
com.raytheon.uf.common.util.collections,
com.raytheon.uf.common.util.concurrent,
com.raytheon.uf.common.util.file,
com.raytheon.uf.common.util.header,

View file

@ -0,0 +1,141 @@
/**
* 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.common.util.collections;
import java.util.Collection;
/**
* Manages a collection that is updated upon access if the time since last
* update is greater than a specified timeout. The user of the collection only
* needs to call the 'get' method to get a read-only collection without worrying
* about updating the collection themselves.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 23, 2014 2701 bclement Initial creation
*
* </pre>
*
* @author bclement
* @version 1.0
*/
public abstract class UpdatingCollection<C extends Collection<T>, T> {
private final long timeoutMillis;
private C collection;
private long lastUpdate;
private boolean enabled = true;
/**
* @param timeoutMillis
* timeout before new update in milliseconds
*/
public UpdatingCollection(long timeoutMillis) {
this.timeoutMillis = timeoutMillis;
}
/**
* Attempt to get timeout from system property
*
* @param timeoutProp
* system property name
* @param defaultTimeoutMillis
* default timeout before new update in milliseconds
*/
public UpdatingCollection(String timeoutProp, long defaultTimeoutMillis) {
this(Long.getLong(timeoutProp, defaultTimeoutMillis));
}
/**
* Update collection. This method will be called if the collection is not
* initialized or if the time since last update is greater than timeout. If
* this method returns null, the time used in the timeout check will not be
* updated and the get method will return an empty collection.
*
* @return null if there was a problem with update
*/
abstract protected C update();
/**
* Access the collection. The returned value is unmodifiable and guaranteed
* to not be null.
*
* @return
*/
public synchronized C get() {
if (!enabled) {
return collection != null ? collection : getEmpty();
}
C rval = collection;
long sinceLastUpdate = System.currentTimeMillis() - lastUpdate;
if (collection == null || sinceLastUpdate > timeoutMillis) {
rval = update();
if (rval != null) {
rval = collection = wrap(rval);
lastUpdate = System.currentTimeMillis();
} else {
rval = getEmpty();
}
}
return rval;
}
/**
* Wrap collection in unmodifiable collection.
*
* @return
*/
protected abstract C wrap(C collection);
/**
* @return an empty, unmodifiable collection
*/
protected abstract C getEmpty();
/**
* Prevent the collection from attempting to update.
*/
public synchronized void disable() {
this.enabled = false;
}
/**
* Allow the collection to attempt to update.
*/
public synchronized void enable() {
this.enabled = true;
}
/**
* @return the timeout in milliseconds
*/
public long getTimeout() {
return timeoutMillis;
}
}

View file

@ -0,0 +1,89 @@
/**
* 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.common.util.collections;
import java.util.Collections;
import java.util.Set;
/**
* Manages a set that is updated upon access if the time since last update is
* greater than a specified timeout. The user of the set only needs to call the
* 'get' method to get a read-only set without worrying about updating the set
* themselves.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 23, 2014 2701 bclement Initial creation
*
* </pre>
*
* @author bclement
* @version 1.0
*/
public abstract class UpdatingSet<T> extends UpdatingCollection<Set<T>, T> {
/**
* @see UpdatingCollection#UpdatingCollection(long)
* @param timeoutMillis
* timeout before new update in milliseconds
*/
public UpdatingSet(long timeoutMillis) {
super(timeoutMillis);
}
/**
* @see UpdatingCollection#UpdatingCollection(String, long)
* @param timeoutProp
* system property name
* @param defaultTimeoutMillis
* default timeout before new update in milliseconds
*/
public UpdatingSet(String timeoutProp, long defaultTimeoutMillis) {
super(timeoutProp, defaultTimeoutMillis);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.util.collections.UpdatingCollection#wrap(java.
* util.Collection)
*/
@Override
protected Set<T> wrap(Set<T> collection) {
return Collections.unmodifiableSet(collection);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.util.collections.UpdatingCollection#getEmpty()
*/
@Override
protected Set<T> getEmpty() {
return Collections.emptySet();
}
}