Issue #2563 compatibility features for stock xmpp servers
added more listener handling for venue events and server disconnection added capability to connect to a different server from UI added better error messages for failed connection/login to server fixed assumptions that server always sends HTTP url and has feed chatroom Former-commit-id: b3173727f3f685119be3668779eb5da7e075df50
This commit is contained in:
parent
54a986613a
commit
09c0267237
16 changed files with 815 additions and 213 deletions
|
@ -33,6 +33,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 20, 2012 jkorman Initial creation
|
||||
* Dec 19, 2013 2563 bclement added description getter
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -56,4 +57,9 @@ public interface IVenueParticipantEvent {
|
|||
* @return presence of participant, may be null
|
||||
*/
|
||||
public Presence getPresence();
|
||||
|
||||
/**
|
||||
* @return description of participant update event, may be null
|
||||
*/
|
||||
public String getEventDescription();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
* 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.event;
|
||||
|
||||
/**
|
||||
* Event sent when the server drops connection with the client
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Dec 19, 2013 2563 bclement Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bclement
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class ServerDisconnectEvent {
|
||||
|
||||
private final String reason;
|
||||
|
||||
/**
|
||||
* @param reason
|
||||
*/
|
||||
public ServerDisconnectEvent(String reason) {
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the reason
|
||||
*/
|
||||
public String getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
}
|
|
@ -35,6 +35,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 20, 2012 jkorman Initial creation
|
||||
* Dec 19, 2013 2563 bclement added description
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -50,6 +51,8 @@ public class VenueParticipantEvent implements IVenueParticipantEvent {
|
|||
|
||||
private Presence presence;
|
||||
|
||||
private String eventDescription;
|
||||
|
||||
public VenueParticipantEvent(UserId participant,
|
||||
ParticipantEventType eventType) {
|
||||
this.participant = participant;
|
||||
|
@ -87,4 +90,24 @@ public class VenueParticipantEvent implements IVenueParticipantEvent {
|
|||
return presence;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.uf.viz.collaboration.comm.identity.event.IVenueParticipantEvent
|
||||
* #getEventDescription()
|
||||
*/
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return eventDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param eventDescription
|
||||
* the eventDescription to set
|
||||
*/
|
||||
public void setEventDescription(String eventDescription) {
|
||||
this.eventDescription = eventDescription;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* 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.event;
|
||||
|
||||
/**
|
||||
* Event sent when actions are taken on the user in the venue (kicked, banned,
|
||||
* granted/revoked privileges, etc)
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Dec 19, 2013 2563 bclement Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bclement
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class VenueUserEvent {
|
||||
|
||||
private final String message;
|
||||
|
||||
/**
|
||||
* @param message
|
||||
*/
|
||||
public VenueUserEvent(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the message
|
||||
*/
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
|
@ -28,6 +28,7 @@ import java.util.Map;
|
|||
import org.apache.commons.lang.StringUtils;
|
||||
import org.jivesoftware.smack.Connection;
|
||||
import org.jivesoftware.smack.ConnectionConfiguration;
|
||||
import org.jivesoftware.smack.ConnectionListener;
|
||||
import org.jivesoftware.smack.Roster;
|
||||
import org.jivesoftware.smack.RosterEntry;
|
||||
import org.jivesoftware.smack.RosterListener;
|
||||
|
@ -38,6 +39,8 @@ import org.jivesoftware.smack.packet.Message;
|
|||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jivesoftware.smack.packet.Presence.Mode;
|
||||
import org.jivesoftware.smack.packet.Presence.Type;
|
||||
import org.jivesoftware.smack.packet.StreamError;
|
||||
import org.jivesoftware.smack.packet.XMPPError;
|
||||
import org.jivesoftware.smack.provider.ProviderManager;
|
||||
import org.jivesoftware.smackx.muc.InvitationListener;
|
||||
import org.jivesoftware.smackx.muc.MultiUserChat;
|
||||
|
@ -65,6 +68,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.SessionPayload.PayloadTyp
|
|||
import com.raytheon.uf.viz.collaboration.comm.provider.SessionPayloadProvider;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.Tools;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.RosterChangeEvent;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.ServerDisconnectEvent;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.VenueInvitationEvent;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.info.VenueInfo;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.ContactsManager;
|
||||
|
@ -100,6 +104,8 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueId;
|
|||
* Apr 18, 2012 njensen Major cleanup
|
||||
* Dec 6, 2013 2561 bclement removed ECF
|
||||
* Dec 18, 2013 2562 bclement added smack compression, fixed invite parsing
|
||||
* Dec 19, 2013 2563 bclement added connection listener,
|
||||
* added better error message on failed connection
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -180,15 +186,10 @@ public class CollaborationConnection implements IEventPublisher {
|
|||
|
||||
this.user = new UserId(connectionData.getUserName(),
|
||||
connectionData.getServer());
|
||||
try {
|
||||
connection.connect();
|
||||
connection.login(user.getName(), password);
|
||||
} catch (XMPPException e) {
|
||||
closeInternals();
|
||||
throw new CollaborationException("Login failed.", e);
|
||||
|
||||
}
|
||||
connectInternal(user.getName(), password);
|
||||
|
||||
setupConnectionListener();
|
||||
setupAccountManager();
|
||||
setupInternalConnectionListeners();
|
||||
setupInternalVenueInvitationListener();
|
||||
|
@ -209,6 +210,44 @@ public class CollaborationConnection implements IEventPublisher {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* connect to XMPP server and login
|
||||
*
|
||||
* @param username
|
||||
* @param password
|
||||
* @throws CollaborationException
|
||||
*/
|
||||
private void connectInternal(String username, String password)
|
||||
throws CollaborationException {
|
||||
try {
|
||||
connection.connect();
|
||||
connection.login(username, password);
|
||||
} catch (XMPPException e) {
|
||||
closeInternals();
|
||||
// get a nice reason for the user
|
||||
String msg;
|
||||
XMPPError xmppErr = e.getXMPPError();
|
||||
if (xmppErr != null) {
|
||||
switch (xmppErr.getCode()) {
|
||||
case 401:
|
||||
msg = "Bad username or password";
|
||||
break;
|
||||
case 403:
|
||||
msg = "User not allowed to connect to server";
|
||||
break;
|
||||
case 409:
|
||||
msg = "User account already in use by another client";
|
||||
break;
|
||||
default:
|
||||
msg = e.getLocalizedMessage();
|
||||
}
|
||||
} else {
|
||||
msg = e.getLocalizedMessage();
|
||||
}
|
||||
throw new CollaborationException("Login failed: " + msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
public CollaborationConnectionData getConnectionData() {
|
||||
return connectionData;
|
||||
}
|
||||
|
@ -299,6 +338,7 @@ public class CollaborationConnection implements IEventPublisher {
|
|||
connection.disconnect();
|
||||
connection = null;
|
||||
}
|
||||
PeerToPeerCommHelper.reset();
|
||||
instanceMap.remove(connectionData);
|
||||
if (this == instance) {
|
||||
instance = null;
|
||||
|
@ -405,6 +445,22 @@ public class CollaborationConnection implements IEventPublisher {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if venue exists on server
|
||||
*
|
||||
* @param venueName
|
||||
* @return false on error
|
||||
*/
|
||||
public boolean venueExistsOnServer(String venueName) {
|
||||
String roomId = VenueSession.getRoomId(connection.getHost(), venueName);
|
||||
try {
|
||||
return VenueSession.roomExistsOnServer(connection, roomId);
|
||||
} catch (XMPPException e) {
|
||||
statusHandler.error("Unable to check for room on server", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param venueName
|
||||
|
@ -529,6 +585,65 @@ public class CollaborationConnection implements IEventPublisher {
|
|||
}
|
||||
}
|
||||
|
||||
private void setupConnectionListener(){
|
||||
if (isConnected()){
|
||||
connection.addConnectionListener(new ConnectionListener() {
|
||||
|
||||
@Override
|
||||
public void reconnectionSuccessful() {
|
||||
statusHandler.debug("Client successfully reconnected to server");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reconnectionFailed(Exception e) {
|
||||
String reason = getErrorReason(e);
|
||||
statusHandler.error("Client can't reconnect to server: "
|
||||
+ reason, e);
|
||||
sendDisconnectNotice(reason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reconnectingIn(int seconds) {
|
||||
statusHandler.debug("Client reconnecting to server in " + seconds + " seconds" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectionClosedOnError(Exception e) {
|
||||
String reason = getErrorReason(e);
|
||||
statusHandler.error("Server closed on error: " + reason, e);
|
||||
sendDisconnectNotice(reason);
|
||||
}
|
||||
|
||||
private String getErrorReason(Exception e) {
|
||||
String msg = null;
|
||||
if (e instanceof XMPPException) {
|
||||
StreamError streamError = ((XMPPException) e)
|
||||
.getStreamError();
|
||||
if (streamError != null) {
|
||||
if ("conflict".equalsIgnoreCase(streamError
|
||||
.getCode())) {
|
||||
msg = "User account in use on another client";
|
||||
}
|
||||
}
|
||||
}
|
||||
return msg == null ? e.getLocalizedMessage() : msg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectionClosed() {
|
||||
statusHandler.info("Server closed connection");
|
||||
sendDisconnectNotice("Normal termination");
|
||||
}
|
||||
|
||||
private void sendDisconnectNotice(String reason) {
|
||||
ServerDisconnectEvent event = new ServerDisconnectEvent(
|
||||
reason);
|
||||
eventBus.post(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// ***************************
|
||||
// Venue invitation listener management
|
||||
// ***************************
|
||||
|
@ -558,7 +673,8 @@ public class CollaborationConnection implements IEventPublisher {
|
|||
return;
|
||||
}
|
||||
}
|
||||
if ( reason.startsWith(Tools.CMD_PREAMBLE)){
|
||||
if (reason != null
|
||||
&& reason.startsWith(Tools.CMD_PREAMBLE)) {
|
||||
reason = "Shared display invitation from incompatible version of CAVE. "
|
||||
+ "Session will be chat-only if invitation is accepted";
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter;
|
|||
* Dec 6, 2013 2561 bclement removed ECF
|
||||
* Dec 18, 2013 2562 bclement added timeout for HTTP config,
|
||||
* data now in packet extension
|
||||
* Dec 19, 2013 2563 bclement removed wait for HTTP config, added reset
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -64,41 +65,16 @@ public class PeerToPeerCommHelper implements PacketListener {
|
|||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(PeerToPeerCommHelper.class);
|
||||
|
||||
private static Object httpServerLockObj = new Object();
|
||||
|
||||
private static String httpServer;
|
||||
private static volatile String httpServer;
|
||||
|
||||
private static long HTTP_SERVER_TIMEOUT = 10 * 1000; // 10 seconds
|
||||
|
||||
/**
|
||||
* Get HTTP server address. This method blocks until the address has been
|
||||
* received from the chat server or a timeout has expired.
|
||||
* Get HTTP server address. This value will be updated if the server sends
|
||||
* new HTTP configuration. If this address is null, the server most likely
|
||||
* doesn't support collaborative displays.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getCollaborationHttpServer() {
|
||||
/**
|
||||
* Wait for initialization of field httpServer.
|
||||
*/
|
||||
synchronized (httpServerLockObj) {
|
||||
long start = System.currentTimeMillis();
|
||||
try {
|
||||
while (httpServer == null) {
|
||||
if (System.currentTimeMillis() - start > HTTP_SERVER_TIMEOUT) {
|
||||
// TODO should we get fallback server address from
|
||||
// localization?
|
||||
statusHandler
|
||||
.error("HTTP URL configuration not received from server");
|
||||
break;
|
||||
}
|
||||
httpServerLockObj.wait(500);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
"PeerToPeerCommHelper unable to resolve server URL. "
|
||||
+ e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
return httpServer;
|
||||
}
|
||||
|
||||
|
@ -262,10 +238,7 @@ public class PeerToPeerCommHelper implements PacketListener {
|
|||
return;
|
||||
}
|
||||
|
||||
synchronized (httpServerLockObj) {
|
||||
httpServer = httpdCollaborationURL;
|
||||
httpServerLockObj.notifyAll();
|
||||
}
|
||||
httpServer = httpdCollaborationURL;
|
||||
// configuration is valid; publish it.
|
||||
IHttpdCollaborationConfigurationEvent configurationEvent = new HttpdCollaborationConfigurationEvent(
|
||||
httpdCollaborationURL);
|
||||
|
@ -296,4 +269,11 @@ public class PeerToPeerCommHelper implements PacketListener {
|
|||
manager.postEvent(configurationEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* reset internal state when client disconnects from server
|
||||
*/
|
||||
public static void reset() {
|
||||
httpServer = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.jivesoftware.smackx.Form;
|
|||
import org.jivesoftware.smackx.ServiceDiscoveryManager;
|
||||
import org.jivesoftware.smackx.muc.MultiUserChat;
|
||||
import org.jivesoftware.smackx.muc.ParticipantStatusListener;
|
||||
import org.jivesoftware.smackx.muc.UserStatusListener;
|
||||
import org.jivesoftware.smackx.packet.DiscoverItems;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
@ -53,7 +54,9 @@ import com.raytheon.uf.viz.collaboration.comm.provider.SessionPayload;
|
|||
import com.raytheon.uf.viz.collaboration.comm.provider.SessionPayload.PayloadType;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.TextMessage;
|
||||
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.event.VenueParticipantEvent;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.VenueUserEvent;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.info.Venue;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
||||
|
@ -83,6 +86,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
|||
* Apr 17, 2012 njensen Major refactor
|
||||
* Dec 6, 2013 2561 bclement removed ECF
|
||||
* Dec 18, 2013 2562 bclement moved data to packet extension
|
||||
* Dec 19, 2013 2563 bclement status listeners now send all events to bus
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -265,7 +269,7 @@ public class VenueSession extends BaseSession implements IVenueSession {
|
|||
* @param roomName
|
||||
* @return
|
||||
*/
|
||||
private String getRoomId(String host, String roomName) {
|
||||
public static String getRoomId(String host, String roomName) {
|
||||
return roomName + "@conference." + host;
|
||||
}
|
||||
|
||||
|
@ -284,7 +288,7 @@ public class VenueSession extends BaseSession implements IVenueSession {
|
|||
CollaborationConnection manager = getSessionManager();
|
||||
XMPPConnection conn = manager.getXmppConnection();
|
||||
String roomId = getRoomId(conn.getHost(), venueName);
|
||||
if (roomExistsOnServer(roomId)) {
|
||||
if (roomExistsOnServer(conn, roomId)) {
|
||||
throw new CollaborationException("Session name already in use");
|
||||
}
|
||||
this.muc = new MultiUserChat(conn, roomId);
|
||||
|
@ -307,10 +311,9 @@ public class VenueSession extends BaseSession implements IVenueSession {
|
|||
* @return true if room exists on server
|
||||
* @throws XMPPException
|
||||
*/
|
||||
protected boolean roomExistsOnServer(String roomId) throws XMPPException {
|
||||
public static boolean roomExistsOnServer(XMPPConnection conn, String roomId)
|
||||
throws XMPPException {
|
||||
String host = Tools.parseHost(roomId);
|
||||
CollaborationConnection manager = getSessionManager();
|
||||
XMPPConnection conn = manager.getXmppConnection();
|
||||
ServiceDiscoveryManager serviceDiscoveryManager = new ServiceDiscoveryManager(
|
||||
conn);
|
||||
DiscoverItems result = serviceDiscoveryManager.discoverItems(host);
|
||||
|
@ -333,95 +336,105 @@ public class VenueSession extends BaseSession implements IVenueSession {
|
|||
|
||||
@Override
|
||||
public void voiceRevoked(String participant) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
sendParticipantEvent(participant, ParticipantEventType.UPDATED,
|
||||
"is no longer allowed to chat.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void voiceGranted(String participant) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
sendParticipantEvent(participant, ParticipantEventType.UPDATED,
|
||||
"is now allowed to chat.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ownershipRevoked(String participant) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
sendParticipantEvent(participant, ParticipantEventType.UPDATED,
|
||||
"is no longer a room owner.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ownershipGranted(String participant) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
sendParticipantEvent(participant, ParticipantEventType.UPDATED,
|
||||
"is now a room owner.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nicknameChanged(String participant, String newNickname) {
|
||||
// TODO how do we pass along new nickname?
|
||||
UserId user = IDConverter.convertFromRoom(muc, participant);
|
||||
postEvent(new VenueParticipantEvent(user,
|
||||
ParticipantEventType.UPDATED));
|
||||
postEvent(new UserNicknameChangedEvent(user, newNickname));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moderatorRevoked(String participant) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
sendParticipantEvent(participant, ParticipantEventType.UPDATED,
|
||||
"is no longer a moderator.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moderatorGranted(String participant) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
sendParticipantEvent(participant, ParticipantEventType.UPDATED,
|
||||
"is now a moderator.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void membershipRevoked(String participant) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
sendParticipantEvent(participant, ParticipantEventType.UPDATED,
|
||||
"is no longer a member of the room.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void membershipGranted(String participant) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
sendParticipantEvent(participant, ParticipantEventType.UPDATED,
|
||||
"is now a member of the room.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void left(String participant) {
|
||||
UserId user = IDConverter.convertFromRoom(muc, participant);
|
||||
postEvent(new VenueParticipantEvent(user,
|
||||
ParticipantEventType.DEPARTED));
|
||||
|
||||
sendParticipantEvent(participant,
|
||||
ParticipantEventType.DEPARTED, "has left the room.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void kicked(String participant, String actor, String reason) {
|
||||
this.left(participant);
|
||||
// no period since formatter adds it
|
||||
sendParticipantEvent(participant,
|
||||
ParticipantEventType.DEPARTED,
|
||||
formatEjectionString("has been kicked", actor, reason));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void joined(String participant) {
|
||||
UserId user = IDConverter.convertFromRoom(muc, participant);
|
||||
postEvent(new VenueParticipantEvent(user,
|
||||
ParticipantEventType.ARRIVED));
|
||||
sendParticipantEvent(participant, ParticipantEventType.ARRIVED,
|
||||
"has entered the room.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void banned(String participant, String actor, String reason) {
|
||||
this.left(participant);
|
||||
// no period since formatter adds it
|
||||
sendParticipantEvent(participant,
|
||||
ParticipantEventType.DEPARTED,
|
||||
formatEjectionString("has been banned", actor, reason));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void adminRevoked(String participant) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
sendParticipantEvent(participant, ParticipantEventType.UPDATED,
|
||||
"is no longer an admin.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void adminGranted(String participant) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
sendParticipantEvent(participant, ParticipantEventType.UPDATED,
|
||||
"is now an admin.");
|
||||
}
|
||||
|
||||
private void sendParticipantEvent(String participant,
|
||||
ParticipantEventType type, String desciption) {
|
||||
UserId user = IDConverter.convertFromRoom(muc, participant);
|
||||
VenueParticipantEvent event = new VenueParticipantEvent(user,
|
||||
ParticipantEventType.ARRIVED);
|
||||
event.setEventDescription(desciption);
|
||||
postEvent(event);
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -456,6 +469,103 @@ public class VenueSession extends BaseSession implements IVenueSession {
|
|||
|
||||
}
|
||||
});
|
||||
// listens for our own status changes
|
||||
this.muc.addUserStatusListener(new UserStatusListener() {
|
||||
|
||||
@Override
|
||||
public void voiceRevoked() {
|
||||
sendUserEvent("Your chat privileges have been revoked.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void voiceGranted() {
|
||||
sendUserEvent("Your chat privileges have been granted.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ownershipRevoked() {
|
||||
sendUserEvent("You are no longer an owner of this room.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ownershipGranted() {
|
||||
sendUserEvent("You are now an owner of this room.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moderatorRevoked() {
|
||||
sendUserEvent("You are no longer a moderator of this room.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moderatorGranted() {
|
||||
sendUserEvent("You are now the moderator of this room.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void membershipRevoked() {
|
||||
sendUserEvent("You are no longer a member of this room.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void membershipGranted() {
|
||||
sendUserEvent("You are now a member of this room.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void kicked(String actor, String reason) {
|
||||
// no period since formatter adds it
|
||||
sendUserEvent(formatEjectionString("You have had been kicked",
|
||||
actor, reason));
|
||||
// TODO disable window?
|
||||
}
|
||||
|
||||
@Override
|
||||
public void banned(String actor, String reason) {
|
||||
// no period since formatter adds it
|
||||
sendUserEvent(formatEjectionString("You have been banned",
|
||||
actor, reason));
|
||||
// TODO disable window?
|
||||
}
|
||||
|
||||
@Override
|
||||
public void adminRevoked() {
|
||||
sendUserEvent("You have had admin privileges revoked.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void adminGranted() {
|
||||
sendUserEvent("You have had admin privileges granted.");
|
||||
}
|
||||
|
||||
private void sendUserEvent(String message) {
|
||||
postEvent(new VenueUserEvent(message));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Format reason for being kicked/banned from venue. Actor and reason will
|
||||
* be appended to base if not null or empty. Formatter will add period at
|
||||
* end of string.
|
||||
*
|
||||
* @param base
|
||||
* @param actor
|
||||
* @param reason
|
||||
* @return
|
||||
*/
|
||||
private String formatEjectionString(String base, String actor, String reason) {
|
||||
StringBuilder rval = new StringBuilder(base);
|
||||
if (!StringUtils.isBlank(actor)) {
|
||||
rval.append(" by ").append(actor);
|
||||
}
|
||||
if (!StringUtils.isBlank(reason)) {
|
||||
rval.append(" with reason '").append(reason).append("'");
|
||||
} else {
|
||||
rval.append(" with no reason given");
|
||||
}
|
||||
rval.append(".");
|
||||
return rval.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -563,10 +673,10 @@ public class VenueSession extends BaseSession implements IVenueSession {
|
|||
}
|
||||
|
||||
/**
|
||||
* Convert from an ECF chat room message to an IMessage instance.
|
||||
* Convert from an chat room message to an IMessage instance.
|
||||
*
|
||||
* @param msg
|
||||
* The ECF chat room message to convert.
|
||||
* The chat room message to convert.
|
||||
* @return The converted message.
|
||||
*/
|
||||
private IMessage convertMessage(Message msg) {
|
||||
|
|
|
@ -83,6 +83,7 @@ import org.osgi.framework.Bundle;
|
|||
import com.google.common.eventbus.Subscribe;
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession;
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.event.IRosterChangeEvent;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.ServerDisconnectEvent;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.UserNicknameChangedEvent;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.UserPresenceChangedEvent;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
|
||||
|
@ -132,6 +133,7 @@ import com.raytheon.viz.ui.views.CaveFloatingView;
|
|||
* Mar 1, 2012 rferrel Initial creation
|
||||
* 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
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -166,6 +168,8 @@ public class CollaborationGroupView extends CaveFloatingView implements
|
|||
|
||||
private Image pressedImage = null;
|
||||
|
||||
private LogoutAction logOut;
|
||||
|
||||
/**
|
||||
* @param parent
|
||||
*/
|
||||
|
@ -320,7 +324,8 @@ public class CollaborationGroupView extends CaveFloatingView implements
|
|||
mgr.add(new Separator());
|
||||
|
||||
if (CollaborationConnection.getConnection() != null) {
|
||||
mgr.add(new LogoutAction());
|
||||
logOut = new LogoutAction();
|
||||
mgr.add(logOut);
|
||||
} else {
|
||||
mgr.add(new LoginAction());
|
||||
}
|
||||
|
@ -876,4 +881,18 @@ public class CollaborationGroupView extends CaveFloatingView implements
|
|||
public void userNicknameChanged(UserNicknameChangedEvent e) {
|
||||
refreshUsersTreeViewerAsync(usersTreeViewer.getInput());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void serverDisconnected(final ServerDisconnectEvent e) {
|
||||
if (logOut == null) {
|
||||
// we aren't logged in
|
||||
return;
|
||||
}
|
||||
VizApp.runAsync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
logOut.closeCollaboration();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@ import com.raytheon.uf.viz.collaboration.comm.identity.info.IVenueInfo;
|
|||
import com.raytheon.uf.viz.collaboration.comm.identity.user.SharedDisplayRole;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.Tools;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.PeerToPeerCommHelper;
|
||||
import com.raytheon.uf.viz.collaboration.display.data.SharedDisplaySessionMgr;
|
||||
import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.ISharedEditorsManagerListener;
|
||||
import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.SharedEditorsManager;
|
||||
|
@ -81,6 +82,7 @@ import com.raytheon.viz.ui.editor.IMultiPaneEditor;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Feb 15, 2012 rferrel Initial creation
|
||||
* Dec 19, 2013 2563 bclement disable shared display option if not supported by server
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -265,31 +267,24 @@ public class CreateSessionDialog extends CaveSWTDialog {
|
|||
IEditorPart editor = EditorUtil.getActiveEditorAs(IEditorPart.class);
|
||||
|
||||
if (!sharedSessionDisplay.isDisposed()) {
|
||||
if (editor instanceof CollaborationEditor) {
|
||||
sharedSessionDisplay
|
||||
.setText("Create Shared Display Session *Client Session*");
|
||||
sharedSessionDisplay.setEnabled(false);
|
||||
sharedSessionDisplay.setSelection(false);
|
||||
sharedSessionDisplay.getParent().setToolTipText(
|
||||
if (!serverSupportsSharing()) {
|
||||
disableShareOption(
|
||||
"Not Supported By Server",
|
||||
"Unable to create a shared display session because"
|
||||
+ " the server doesn't support shared display sessions.");
|
||||
} else if (editor instanceof CollaborationEditor) {
|
||||
disableShareOption("Client Session",
|
||||
"Unable to create a shared display session because"
|
||||
+ " the active editor is a client session.");
|
||||
} else if (!isShareable(editor)) {
|
||||
sharedSessionDisplay
|
||||
.setText("Create Shared Display Session *Not Shareable*");
|
||||
sharedSessionDisplay.setEnabled(false);
|
||||
sharedSessionDisplay.setSelection(false);
|
||||
sharedSessionDisplay.getParent().setToolTipText(
|
||||
disableShareOption("Not Shareable",
|
||||
"Unable to create a shared display session because"
|
||||
+ " the active editor is not shareable.");
|
||||
} else if (editor != null
|
||||
&& editor instanceof AbstractEditor
|
||||
&& SharedEditorsManager
|
||||
.isBeingShared((AbstractEditor) editor)) {
|
||||
sharedSessionDisplay
|
||||
.setText("Create Shared Display Session *Already Shared*");
|
||||
sharedSessionDisplay.setEnabled(false);
|
||||
sharedSessionDisplay.setSelection(false);
|
||||
sharedSessionDisplay.getParent().setToolTipText(
|
||||
disableShareOption("Already Shared",
|
||||
"Unable to create a shared display session because"
|
||||
+ " the active editor is already "
|
||||
+ "in a shared display session.");
|
||||
|
@ -301,6 +296,28 @@ public class CreateSessionDialog extends CaveSWTDialog {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable create shared display checkbox
|
||||
*
|
||||
* @param shortReason
|
||||
* @param longReason
|
||||
*/
|
||||
private void disableShareOption(String shortReason, String longReason) {
|
||||
String text = String.format("Create Shared Display Session *%s*",
|
||||
shortReason);
|
||||
sharedSessionDisplay.setText(text);
|
||||
sharedSessionDisplay.setEnabled(false);
|
||||
sharedSessionDisplay.setSelection(false);
|
||||
sharedSessionDisplay.getParent().setToolTipText(longReason);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the server supports shared display sessions
|
||||
*/
|
||||
private boolean serverSupportsSharing() {
|
||||
return PeerToPeerCommHelper.getCollaborationHttpServer() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void disposed() {
|
||||
super.disposed();
|
||||
|
|
|
@ -53,6 +53,7 @@ import com.raytheon.viz.ui.views.CaveWorkbenchPageManager;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 5, 2012 bsteffen Initial creation
|
||||
* Dec 19, 2013 2563 bclement added check for feed venue existence
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -113,6 +114,14 @@ public class DisplayFeedAction extends Action {
|
|||
|
||||
@Override
|
||||
public void run() {
|
||||
CollaborationConnection connection = CollaborationConnection
|
||||
.getConnection();
|
||||
if (!connection.venueExistsOnServer(FEED_VENUE)) {
|
||||
statusHandler.info("Feed venue doesn't exist on server: "
|
||||
+ FEED_VENUE);
|
||||
return;
|
||||
}
|
||||
|
||||
// handle if it is clicked to close or open the view as
|
||||
// necessary
|
||||
CaveWorkbenchPageManager page = CaveWorkbenchPageManager
|
||||
|
|
|
@ -53,6 +53,7 @@ import com.raytheon.viz.ui.views.CaveWorkbenchPageManager;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 11, 2012 bsteffen Initial creation
|
||||
* Dec 19, 2013 2563 bclement moved close logic to public method
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -81,35 +82,44 @@ public class LogoutAction extends Action {
|
|||
+ "close all collaboration views\n" + "and editors.");
|
||||
int result = messageBox.open();
|
||||
if (result == SWT.OK) {
|
||||
for (IViewReference ref : CaveWorkbenchPageManager
|
||||
.getActiveInstance().getViewReferences()) {
|
||||
IViewPart view = ref.getView(false);
|
||||
if (view instanceof AbstractSessionView
|
||||
|| view instanceof CollaborationGroupView) {
|
||||
CaveWorkbenchPageManager.getActiveInstance().hideView(ref);
|
||||
}
|
||||
}
|
||||
|
||||
// Close all Collaboration Editors.
|
||||
for (IEditorReference ref : PlatformUI.getWorkbench()
|
||||
.getActiveWorkbenchWindow().getActivePage()
|
||||
.getEditorReferences()) {
|
||||
IEditorPart editor = ref.getEditor(false);
|
||||
if (editor instanceof CollaborationEditor) {
|
||||
PlatformUI.getWorkbench().getActiveWorkbenchWindow()
|
||||
.getActivePage().hideEditor(ref);
|
||||
}
|
||||
}
|
||||
try {
|
||||
Activator.getDefault().getPreferenceStore().save();
|
||||
} catch (IOException e) {
|
||||
statusHandler.handle(Priority.WARN,
|
||||
"Unable to save preferences", e);
|
||||
}
|
||||
CollaborationConnection connection = CollaborationConnection
|
||||
.getConnection();
|
||||
ConnectionSubscriber.unsubscribe(connection);
|
||||
connection.close();
|
||||
closeCollaboration();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close collaboration UI and close connection
|
||||
*
|
||||
*/
|
||||
public void closeCollaboration() {
|
||||
for (IViewReference ref : CaveWorkbenchPageManager.getActiveInstance()
|
||||
.getViewReferences()) {
|
||||
IViewPart view = ref.getView(false);
|
||||
if (view instanceof AbstractSessionView
|
||||
|| view instanceof CollaborationGroupView) {
|
||||
CaveWorkbenchPageManager.getActiveInstance().hideView(ref);
|
||||
}
|
||||
}
|
||||
|
||||
// Close all Collaboration Editors.
|
||||
for (IEditorReference ref : PlatformUI.getWorkbench()
|
||||
.getActiveWorkbenchWindow().getActivePage()
|
||||
.getEditorReferences()) {
|
||||
IEditorPart editor = ref.getEditor(false);
|
||||
if (editor instanceof CollaborationEditor) {
|
||||
PlatformUI.getWorkbench().getActiveWorkbenchWindow()
|
||||
.getActivePage().hideEditor(ref);
|
||||
}
|
||||
}
|
||||
try {
|
||||
Activator.getDefault().getPreferenceStore().save();
|
||||
} catch (IOException e) {
|
||||
statusHandler
|
||||
.handle(Priority.WARN, "Unable to save preferences", e);
|
||||
}
|
||||
CollaborationConnection connection = CollaborationConnection
|
||||
.getConnection();
|
||||
ConnectionSubscriber.unsubscribe(connection);
|
||||
connection.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ import com.raytheon.uf.viz.collaboration.ui.prefs.CollabPrefConstants;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 18, 2012 mschenke Initial creation
|
||||
* Dec 19, 2013 2563 bclement added option to connect to server not in list
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -74,9 +75,7 @@ import com.raytheon.uf.viz.collaboration.ui.prefs.CollabPrefConstants;
|
|||
|
||||
public class LoginDialog extends Dialog {
|
||||
|
||||
private static final String SERVER_ENABLED = "OK";
|
||||
|
||||
private static final String SERVER_DISABLED = "Edit";
|
||||
private static final String OTHER_SERVER_OPTION = "Other server...";
|
||||
|
||||
private IPreferenceStore preferences;
|
||||
|
||||
|
@ -156,29 +155,25 @@ public class LoginDialog extends Dialog {
|
|||
// retrieve the servers
|
||||
SiteConfigInformation information = SiteConfigurationManager
|
||||
.getSiteConfigInformation();
|
||||
if (information.getServer() == null
|
||||
|| information.getServer().size() == 0) {
|
||||
String[] text = new String[1];
|
||||
text[0] = "Server not configured.";
|
||||
serverText.setData("configured", false);
|
||||
serverText.setItems(text);
|
||||
serverText.setText(text[0]);
|
||||
} else {
|
||||
// put configured as true so we don't disable the login button
|
||||
serverText.setData("configured", true);
|
||||
List<HostConfig> servers = information.getServer();
|
||||
String[] names = new String[servers.size()];
|
||||
int index = 0;
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
names[i] = servers.get(i).getPrettyName() + " : "
|
||||
+ servers.get(i).getHostname();
|
||||
if (loginData.getServer().equals(names[i])) {
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
serverText.setItems(names);
|
||||
serverText.select(index);
|
||||
List<HostConfig> servers = information.getServer();
|
||||
if (servers == null) {
|
||||
servers = new ArrayList<SiteConfigInformation.HostConfig>(0);
|
||||
}
|
||||
// put configured as true so we don't disable the login button
|
||||
serverText.setData("configured", true);
|
||||
String[] names = new String[servers.size() + 1];
|
||||
names[0] = OTHER_SERVER_OPTION;
|
||||
int index = 1;
|
||||
for (int i = 1; i < names.length; i++) {
|
||||
HostConfig config = servers.get(i - 1);
|
||||
names[i] = config.getPrettyName() + " : " + config.getHostname();
|
||||
if (loginData.getServer().equals(names[i])) {
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
serverText.setItems(names);
|
||||
serverText.select(index);
|
||||
serverText.addListener(SWT.Selection, new ServerInput(serverText, 0));
|
||||
|
||||
// Password setting
|
||||
new Label(body, SWT.NONE).setText("Password: ");
|
||||
|
@ -312,10 +307,20 @@ public class LoginDialog extends Dialog {
|
|||
loginData
|
||||
.setUserName(loginData.getUserName().toLowerCase());
|
||||
}
|
||||
|
||||
if (loginData.getServer().isEmpty()) {
|
||||
String server = loginData.getServer();
|
||||
if (server.isEmpty()) {
|
||||
errorMessages.add("Must have a server.");
|
||||
}
|
||||
String error = ServerInput.validate(server);
|
||||
if (error != null) {
|
||||
errorMessages.add(error);
|
||||
} else {
|
||||
try {
|
||||
loginData.setServer(ServerInput.getFullName(server));
|
||||
} catch (CollaborationException e) {
|
||||
errorMessages.add(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (loginData.getPassword().isEmpty()) {
|
||||
errorMessages.add("Must enter a password.");
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
/**
|
||||
* 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.login;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.eclipse.jface.dialogs.InputDialog;
|
||||
import org.eclipse.jface.window.Window;
|
||||
import org.eclipse.swt.widgets.Combo;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.swt.widgets.Event;
|
||||
import org.eclipse.swt.widgets.Listener;
|
||||
|
||||
import com.google.common.net.HostAndPort;
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException;
|
||||
|
||||
/**
|
||||
* Listens for add server option in a Combo box, gets new input from user and
|
||||
* appends to the combo box
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Dec 18, 2013 2563 bclement Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bclement
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class ServerInput implements Listener {
|
||||
|
||||
private final Combo serverText;
|
||||
|
||||
private final int addItemIndex;
|
||||
|
||||
private static final int DEFAULT_XMPP_PORT = 5432;
|
||||
|
||||
private static final int TIMEOUT = 5000; // 5 seconds
|
||||
|
||||
|
||||
/**
|
||||
* @param serverText
|
||||
*/
|
||||
public ServerInput(Combo serverText, int addItemIndex) {
|
||||
this.serverText = serverText;
|
||||
this.addItemIndex = addItemIndex;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.
|
||||
* Event)
|
||||
*/
|
||||
@Override
|
||||
public void handleEvent(Event event) {
|
||||
int index = serverText.getSelectionIndex();
|
||||
if (index == addItemIndex) {
|
||||
InputDialog dlg = new InputDialog(Display.getCurrent()
|
||||
.getActiveShell(), "", "Enter server address", "", null);
|
||||
int status = dlg.open();
|
||||
if (status == Window.OK) {
|
||||
String value = dlg.getValue();
|
||||
addToOptions(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Append new server to options combo and select it
|
||||
*
|
||||
* @param server
|
||||
*/
|
||||
private void addToOptions(String server) {
|
||||
String[] items = serverText.getItems();
|
||||
items = Arrays.copyOf(items, items.length + 1);
|
||||
items[items.length - 1] = "Custom Server : " + server;
|
||||
serverText.setItems(items);
|
||||
serverText.select(items.length - 1);
|
||||
// this doesn't persist the new server. I can
|
||||
// see that being a good thing or an annoyance.
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate server by parsing the string and attempting to ping the server.
|
||||
* Returns an error string if server string could not be parsed or server
|
||||
* could not be contacted.
|
||||
*
|
||||
* @param server
|
||||
* @return null if there were no issues
|
||||
*/
|
||||
public static String validate(String server) {
|
||||
Socket s = null;
|
||||
try {
|
||||
HostAndPort hnp = HostAndPort.fromString(server).withDefaultPort(
|
||||
DEFAULT_XMPP_PORT);
|
||||
s = new Socket();
|
||||
s.setReuseAddress(true);
|
||||
SocketAddress sa = new InetSocketAddress(hnp.getHostText(),
|
||||
hnp.getPort());
|
||||
s.connect(sa, TIMEOUT);
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
return "Unable to connect to server: " + e.getLocalizedMessage();
|
||||
} finally {
|
||||
if (s != null) {
|
||||
try {
|
||||
s.close();
|
||||
} catch (IOException e) {
|
||||
// no action
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to get canonical host name for server
|
||||
*
|
||||
* @param server
|
||||
* @return
|
||||
* @throws CollaborationException
|
||||
*/
|
||||
public static String getFullName(String server)
|
||||
throws CollaborationException {
|
||||
try {
|
||||
String hostText = HostAndPort.fromString(server).getHostText();
|
||||
return InetAddress.getByName(hostText).getCanonicalHostName();
|
||||
} catch (Exception e) {
|
||||
throw new CollaborationException("Unable to get full host name", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -92,6 +92,7 @@ import com.raytheon.viz.ui.views.CaveFloatingView;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 16, 2012 244 rferrel Initial creation
|
||||
* Dec 19, 2013 2563 bclement moved color lookup into runAsync block
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -585,35 +586,54 @@ public abstract class AbstractSessionView extends CaveFloatingView {
|
|||
|
||||
protected abstract SessionMsgArchive createMessageArchive();
|
||||
|
||||
/**
|
||||
* display formatted error message on chat window
|
||||
*
|
||||
* @param sb
|
||||
* builder containing message
|
||||
*/
|
||||
protected void sendErrorMessage(StringBuilder sb) {
|
||||
Color color = Display.getCurrent().getSystemColor(SWT.COLOR_RED);
|
||||
sendGenericMessage(sb, color);
|
||||
sendGenericMessage(sb, SWT.COLOR_RED);
|
||||
}
|
||||
|
||||
/**
|
||||
* display formatted error message on chat window
|
||||
*
|
||||
* @param sb
|
||||
* builder containing message
|
||||
*/
|
||||
protected void sendSystemMessage(StringBuilder sb) {
|
||||
Color color = Display.getCurrent().getSystemColor(SWT.COLOR_BLACK);
|
||||
sendGenericMessage(sb, color);
|
||||
sendGenericMessage(sb, SWT.COLOR_BLACK);
|
||||
}
|
||||
|
||||
private void sendGenericMessage(final StringBuilder string,
|
||||
final Color color) {
|
||||
/**
|
||||
* display formatted error message on chat window
|
||||
*
|
||||
* @param builder
|
||||
* builder containing message
|
||||
* @param swtColor
|
||||
* text color for message
|
||||
*/
|
||||
private void sendGenericMessage(final StringBuilder builder,
|
||||
final int swtColor) {
|
||||
VizApp.runAsync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Color color = Display.getCurrent().getSystemColor(swtColor);
|
||||
Date date = new Date();
|
||||
String time = dateFormatter.format(date);
|
||||
string.insert(0, "(" + time + ") : ");
|
||||
builder.insert(0, "(" + time + ") : ");
|
||||
if (messagesText.getCharCount() != 0) {
|
||||
string.insert(0, "\n");
|
||||
builder.insert(0, "\n");
|
||||
}
|
||||
StyleRange range = new StyleRange(messagesText.getCharCount(),
|
||||
string.length(), color, null, SWT.BOLD);
|
||||
builder.length(), color, null, SWT.BOLD);
|
||||
List<StyleRange> ranges = new ArrayList<StyleRange>();
|
||||
ranges.add(range);
|
||||
styleAndAppendText(string, 0, string.toString(), null, ranges,
|
||||
color);
|
||||
msgArchive.archiveLine(string.toString());
|
||||
searchComp.appendText(string.toString());
|
||||
styleAndAppendText(builder, 0, builder.toString(), null,
|
||||
ranges, color);
|
||||
msgArchive.archiveLine(builder.toString());
|
||||
searchComp.appendText(builder.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ import com.raytheon.uf.viz.collaboration.ui.prefs.CollabPrefConstants;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 7, 2012 mnash Initial creation
|
||||
* Dec 6, 2013 2561 bclement removed ECF
|
||||
* Dec 19, 2013 2563 bclement moved participant filter logic to one method
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -357,46 +358,21 @@ public class SessionFeedView extends SessionView {
|
|||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.uf.viz.collaboration.ui.session.SessionView#participantArrived
|
||||
* (com.raytheon.uf.viz.collaboration.comm.provider.user.UserId)
|
||||
* @see com.raytheon.uf.viz.collaboration.ui.session.SessionView#
|
||||
* sendParticipantSystemMessage
|
||||
* (com.raytheon.uf.viz.collaboration.comm.provider.user.UserId,
|
||||
* java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
protected void participantArrived(UserId participant) {
|
||||
setColorForSite(participant);
|
||||
if (session != null && session.getVenue() != null) {
|
||||
Object siteOb = session.getVenue().getPresence(participant)
|
||||
.getProperty(SiteConfigInformation.SITE_NAME);
|
||||
String site = "";
|
||||
if (siteOb != null) {
|
||||
site = siteOb.toString();
|
||||
}
|
||||
// only show sites you care about, or empty site
|
||||
if ("".equals(site) || enabledSites.contains(site)
|
||||
|| userEnabledSites.contains(site)) {
|
||||
super.participantArrived(participant);
|
||||
} else {
|
||||
usersTable.setInput(session.getVenue().getParticipants());
|
||||
usersTable.refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.uf.viz.collaboration.ui.session.SessionView#participantDeparted
|
||||
* (com.raytheon.uf.viz.collaboration.comm.provider.user.UserId)
|
||||
*/
|
||||
@Override
|
||||
protected void participantDeparted(UserId participant) {
|
||||
protected void sendParticipantSystemMessage(UserId participant,
|
||||
String message) {
|
||||
Presence presence = session.getVenue().getPresence(participant);
|
||||
Object siteObj = presence.getProperty(SiteConfigInformation.SITE_NAME);
|
||||
String siteName = siteObj == null ? "" : siteObj.toString();
|
||||
// only show sites you care about
|
||||
if (enabledSites.contains(siteName) || userEnabledSites.contains(siteName)) {
|
||||
super.participantDeparted(participant);
|
||||
if (enabledSites.contains(siteName)
|
||||
|| userEnabledSites.contains(siteName)) {
|
||||
super.sendParticipantSystemMessage(participant, message);
|
||||
} else {
|
||||
usersTable.setInput(session.getVenue().getParticipants());
|
||||
usersTable.refresh();
|
||||
|
|
|
@ -77,6 +77,7 @@ import com.raytheon.uf.viz.collaboration.comm.identity.event.IVenueParticipantEv
|
|||
import com.raytheon.uf.viz.collaboration.comm.identity.event.ParticipantEventType;
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.info.IVenueInfo;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.UserNicknameChangedEvent;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.VenueUserEvent;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.VenueSession;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
||||
|
@ -98,6 +99,7 @@ import com.raytheon.viz.ui.views.CaveWorkbenchPageManager;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 1, 2012 rferrel Initial creation
|
||||
* Dec 6, 2013 2561 bclement removed ECF
|
||||
* Dec 19, 2013 2563 bclement reworked participant event logic
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -636,6 +638,11 @@ public class SessionView extends AbstractSessionView implements IPrintableView {
|
|||
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void userEventHandler(VenueUserEvent event) {
|
||||
sendSystemMessage(new StringBuilder(event.getMessage()));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void participantHandler(IVenueParticipantEvent event)
|
||||
throws Exception {
|
||||
|
@ -643,6 +650,7 @@ public class SessionView extends AbstractSessionView implements IPrintableView {
|
|||
final ParticipantEventType type = event.getEventType();
|
||||
final Presence presence = event.getPresence();
|
||||
final UserId participant = event.getParticipant();
|
||||
final String description = event.getEventDescription();
|
||||
VizApp.runAsync(new Runnable() {
|
||||
|
||||
@Override
|
||||
|
@ -653,16 +661,19 @@ public class SessionView extends AbstractSessionView implements IPrintableView {
|
|||
}
|
||||
switch (type) {
|
||||
case ARRIVED:
|
||||
participantArrived(participant);
|
||||
participantArrived(participant, description);
|
||||
break;
|
||||
case DEPARTED:
|
||||
participantDeparted(participant);
|
||||
participantDeparted(participant, description);
|
||||
break;
|
||||
case PRESENCE_UPDATED:
|
||||
participantPresenceUpdated(participant, presence);
|
||||
break;
|
||||
case UPDATED:
|
||||
// TODO ?
|
||||
usersTable.refresh();
|
||||
if (description != null) {
|
||||
sendParticipantSystemMessage(participant, description);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
System.err.println("Unknown Event type");
|
||||
|
@ -673,31 +684,55 @@ public class SessionView extends AbstractSessionView implements IPrintableView {
|
|||
|
||||
@Subscribe
|
||||
public void userNicknameChanged(UserNicknameChangedEvent e) {
|
||||
usersTable.setInput(session.getVenue().getParticipants());
|
||||
usersTable.refresh();
|
||||
}
|
||||
|
||||
protected void participantArrived(UserId participant) {
|
||||
/**
|
||||
* Update participant list and notify user that new participant joined chat
|
||||
*
|
||||
* @param participant
|
||||
*/
|
||||
protected void participantArrived(UserId participant, String description) {
|
||||
usersTable.setInput(session.getVenue().getParticipants());
|
||||
usersTable.refresh();
|
||||
|
||||
String name = CollaborationConnection.getConnection()
|
||||
.getContactsManager().getDisplayName(participant);
|
||||
StringBuilder builder = new StringBuilder(name
|
||||
+ " has entered the room");
|
||||
sendSystemMessage(builder);
|
||||
String message = description != null ? description
|
||||
: "has entered the room.";
|
||||
sendParticipantSystemMessage(participant, message);
|
||||
}
|
||||
|
||||
protected void participantDeparted(UserId participant) {
|
||||
/**
|
||||
* Update participant list and notify user that new participant left chat
|
||||
*
|
||||
* @param participant
|
||||
*/
|
||||
protected void participantDeparted(UserId participant, String description) {
|
||||
usersTable.setInput(session.getVenue().getParticipants());
|
||||
usersTable.refresh();
|
||||
String message = description != null ? description
|
||||
: "has left the room.";
|
||||
sendParticipantSystemMessage(participant, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send message about about participant. Message is in the form of a
|
||||
* statement pertaining to the participant. For example, to get the output
|
||||
* "Susan was kicked", you would provide Susan's UserId and the message
|
||||
* "was kicked".
|
||||
*
|
||||
* @param participant
|
||||
* @param message
|
||||
*/
|
||||
protected void sendParticipantSystemMessage(UserId participant,
|
||||
String message) {
|
||||
CollaborationConnection connection = CollaborationConnection
|
||||
.getConnection();
|
||||
if (connection != null) {
|
||||
String name = connection.getContactsManager().getDisplayName(
|
||||
participant);
|
||||
|
||||
StringBuilder builder = new StringBuilder(name
|
||||
+ " has left the room");
|
||||
StringBuilder builder = new StringBuilder(name);
|
||||
builder.append(" ").append(message);
|
||||
sendSystemMessage(builder);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue