/* * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. * * Distributable under LGPL license. * See terms of license at gnu.org. */ package net.java.sip.communicator.plugin.whiteboard; import java.awt.*; import java.util.*; import java.util.List; import net.java.sip.communicator.plugin.whiteboard.gui.*; import net.java.sip.communicator.plugin.whiteboard.gui.whiteboardshapes.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.service.protocol.whiteboardobjects.*; import net.java.sip.communicator.util.*; /** * Whiteboard session manager. * * @author Julien Waechter */ public class WhiteboardSessionManager implements WhiteboardObjectListener { private static final Logger logger = Logger.getLogger (WhiteboardSessionManager.class); /** * List active WhitboarFrame started. */ private final java.util.List wbFrames = new Vector(); private OperationSetWhiteboarding opSetWb; public WhiteboardSessionManager() { List whiteboardOpSets = WhiteboardActivator.getWhiteboardOperationSets(); if (whiteboardOpSets == null) return; for (OperationSetWhiteboarding whiteboardOpSet : whiteboardOpSets) { whiteboardOpSet.addInvitationListener(new InvitationListener()); whiteboardOpSet.addPresenceListener(new PresenceListener()); } } /** * Initialize (a new) Whiteboard with contact * * @param contact Contact used to init whiteboard */ public void initWhiteboard (final Contact contact) { opSetWb = contact .getProtocolProvider() .getOperationSet(OperationSetWhiteboarding.class); if (opSetWb == null) { if (logger.isInfoEnabled()) logger.info("Contact does not support whiteboarding"); return; } WhiteboardFrame wbf = getWhiteboardFrame (contact); if(wbf != null) { wbf.setVisible (true); return; } new Thread () { public void run() { try { WhiteboardSession wbSession = opSetWb.createWhiteboardSession ( contact.getDisplayName(), null); WhiteboardFrame wbFrame = new WhiteboardFrame ( WhiteboardSessionManager.this, wbSession); wbFrames.add (wbFrame); wbFrame.setContact(contact); wbFrame.setVisible (true); wbSession.join(); wbSession.invite(contact.getAddress()); } catch (OperationFailedException e) { logger.error("Creating a whiteboard session failed.", e); } catch (OperationNotSupportedException e) { logger.error( "Do not support create of whiteboard session", e); } } }.start(); } /** * Construct (with WhiteboardSession) and send * a WhiteboardObject to a contact. * * @param wbSession the white-board session, to which the object would be * send * @param ws WhiteboardShape to convert and send * @return WhiteboardObject sent */ public WhiteboardObject sendWhiteboardObject ( WhiteboardSession wbSession, WhiteboardShape ws) throws OperationFailedException { Vector supportedWBO = new Vector( Arrays.asList (wbSession.getSupportedWhiteboardObjects ())); if(ws instanceof WhiteboardObjectPath) { if(!supportedWBO.contains (WhiteboardObjectPath.NAME)) return null; WhiteboardObjectPath obj = (WhiteboardObjectPath) wbSession.createWhiteboardObject (WhiteboardObjectPath.NAME ); ws.setID (obj.getID ()); obj.setPoints (((WhiteboardObjectPath)ws).getPoints ()); obj.setColor (ws.getColor ()); obj.setThickness (ws.getThickness ()); wbSession.sendWhiteboardObject (obj); return obj; } else if(ws instanceof WhiteboardObjectPolyLine) { if(!supportedWBO.contains (WhiteboardObjectPolyLine.NAME)) return null; WhiteboardObjectPolyLine obj = (WhiteboardObjectPolyLine) wbSession.createWhiteboardObject (WhiteboardObjectPolyLine.NAME ); ws.setID (obj.getID ()); obj.setPoints (((WhiteboardObjectPolyLine)ws).getPoints ()); obj.setColor (ws.getColor ()); obj.setThickness (ws.getThickness ()); wbSession.sendWhiteboardObject (obj); return obj; } else if(ws instanceof WhiteboardObjectPolygon) { if(!supportedWBO.contains (WhiteboardObjectPolygon.NAME)) return null; WhiteboardObjectPolygon obj = (WhiteboardObjectPolygon) wbSession.createWhiteboardObject (WhiteboardObjectPolygon.NAME ); ws.setID (obj.getID ()); obj.setPoints (((WhiteboardObjectPolygon)ws).getPoints ()); obj.setBackgroundColor (( (WhiteboardObjectPolygon)ws).getBackgroundColor ()); obj.setFill (((WhiteboardObjectPolygon)ws).isFill ()); obj.setColor (ws.getColor ()); obj.setThickness (ws.getThickness ()); wbSession.sendWhiteboardObject (obj); return obj; } else if(ws instanceof WhiteboardObjectLine) { if(!supportedWBO.contains (WhiteboardObjectLine.NAME)) return null; WhiteboardObjectLine obj = (WhiteboardObjectLine) wbSession.createWhiteboardObject (WhiteboardObjectLine.NAME ); ws.setID (obj.getID ()); obj.setWhiteboardPointStart ( ((WhiteboardObjectLine)ws).getWhiteboardPointStart ()); obj.setWhiteboardPointEnd ( ((WhiteboardObjectLine)ws).getWhiteboardPointEnd ()); obj.setColor (ws.getColor ()); obj.setThickness (ws.getThickness ()); wbSession.sendWhiteboardObject (obj); return obj; } else if(ws instanceof WhiteboardObjectRect) { if(!supportedWBO.contains (WhiteboardObjectRect.NAME)) return null; WhiteboardObjectRect obj = (WhiteboardObjectRect) wbSession.createWhiteboardObject (WhiteboardObjectRect.NAME ); ws.setID (obj.getID ()); obj.setFill (((WhiteboardObjectRect)ws).isFill ()); obj.setHeight (((WhiteboardObjectRect)ws).getHeight ()); obj.setWhiteboardPoint ( ((WhiteboardObjectRect)ws).getWhiteboardPoint ()); obj.setWidth ((((WhiteboardObjectRect)ws)).getWidth ()); obj.setColor (ws.getColor ()); obj.setThickness (ws.getThickness ()); wbSession.sendWhiteboardObject (obj); return obj; } else if(ws instanceof WhiteboardObjectCircle) { if(!supportedWBO.contains (WhiteboardObjectCircle.NAME)) return null; WhiteboardObjectCircle obj = (WhiteboardObjectCircle) wbSession.createWhiteboardObject (WhiteboardObjectCircle.NAME ); ws.setID (obj.getID ()); obj.setFill (((WhiteboardObjectCircle)ws).isFill ()); obj.setRadius (((WhiteboardObjectCircle)ws).getRadius ()); obj.setWhiteboardPoint ( ((WhiteboardObjectCircle)ws).getWhiteboardPoint ()); obj.setBackgroundColor ( (((WhiteboardObjectCircle)ws)).getBackgroundColor ()); obj.setColor (ws.getColor ()); obj.setThickness (ws.getThickness ()); wbSession.sendWhiteboardObject (obj); return obj; } else if(ws instanceof WhiteboardObjectText) { if(!supportedWBO.contains (WhiteboardObjectText.NAME)) return null; WhiteboardObjectText obj = (WhiteboardObjectText) wbSession.createWhiteboardObject (WhiteboardObjectText.NAME ); ws.setID (obj.getID ()); obj.setFontName (((WhiteboardObjectText)ws).getFontName ()); obj.setFontSize (((WhiteboardObjectText)ws).getFontSize ()); obj.setText (((WhiteboardObjectText)ws).getText ()); obj.setWhiteboardPoint ( ((WhiteboardObjectText)ws).getWhiteboardPoint ()); obj.setColor (ws.getColor ()); obj.setThickness (ws.getThickness ()); wbSession.sendWhiteboardObject (obj); return obj; } else if(ws instanceof WhiteboardObjectImage) { if(!supportedWBO.contains (WhiteboardObjectImage.NAME)) return null; WhiteboardObjectImage obj = (WhiteboardObjectImage) wbSession.createWhiteboardObject (WhiteboardObjectImage.NAME ); ws.setID (obj.getID ()); obj.setBackgroundImage ( ((WhiteboardObjectImage)ws).getBackgroundImage ()); obj.setHeight (((WhiteboardObjectImage)ws).getHeight ()); obj.setWhiteboardPoint ( ((WhiteboardObjectImage)ws).getWhiteboardPoint ()); obj.setWidth ( ((WhiteboardObjectImage)ws).getWidth ()); obj.setColor (ws.getColor ()); obj.setThickness (ws.getThickness ()); wbSession.sendWhiteboardObject (obj); return obj; } return null; } /** * Moves a WhiteboardShape from from one point to another on the * board. * * @param wbSession the white-board session, to which the moved object * belongs * @param ws the shape to move */ public void moveWhiteboardObject ( WhiteboardSession wbSession, WhiteboardShape ws) { try { wbSession.moveWhiteboardObject (ws); } catch (OperationFailedException ex) { ex.printStackTrace (); } } /** * Deletes a WhiteboardShape from the white-board. * * @param wbSession the white-board session, to which the object belongs * @param ws the shape to delete */ public void deleteWhiteboardObject (WhiteboardSession wbSession, WhiteboardShape ws) { try { wbSession.deleteWhiteboardObject (ws); } catch (OperationFailedException ex) { ex.printStackTrace (); } } /** * Called when a modified WhiteboardObject has been received. * * @param evt the WhiteboardObjectReceivedEvent containing the * modified whiteboardObject, its sender and other details. */ public void whiteboardObjecModified (WhiteboardObjectModifiedEvent evt) { WhiteboardFrame wbf = getWhiteboardFrame ( evt.getSourceWhiteboardSession()); if(wbf == null) return; wbf.setVisible (true); WhiteboardObject wbo = evt.getSourceWhiteboardObject (); wbf.receiveWhiteboardObject (wbo); } /** * Called when a new incoming WhiteboardObject has been received. * * @param evt the WhiteboardObjectReceivedEvent containing * the newly received WhiteboardObject, its sender and other details. */ public void whiteboardObjectReceived (WhiteboardObjectReceivedEvent evt) { /* * There are 2 cases when a message is received: * - an existing session * - or a new session */ WhiteboardFrame wbFrame = getWhiteboardFrame ( evt.getSourceWhiteboardSession()); if(wbFrame == null) { if (logger.isDebugEnabled()) logger.debug ("New WBParticipant" + evt.getSourceContact ().getDisplayName ()); wbFrame = new WhiteboardFrame ( this, evt.getSourceWhiteboardSession()); wbFrames.add (wbFrame); } wbFrame.setVisible (true); WhiteboardObject wbObject = evt.getSourceWhiteboardObject (); wbFrame.receiveWhiteboardObject (wbObject); } /** * Called when the underlying implementation has received an indication * that a WhiteboardObject, sent earlier has been successfully * received by the destination. * * @param evt the WhiteboardObjectDeliveredEvent containing the id of the * WhiteboardObject that has caused the event. */ public void whiteboardObjectDelivered (WhiteboardObjectDeliveredEvent evt) { if (logger.isDebugEnabled()) logger.debug ("WBObjectDeliveredEvent: The following object: " + evt.getSourceWhiteboardObject() + " has been delivered to " + evt.getDestinationContact().getDisplayName()); } /** * Called to indicate that delivery of a WhiteboardObject sent earlier * has failed. * Reason code and phrase are contained by the * WhiteboardObjectDeliveryFailedEvent * * @param evt the WhiteboardObjectDeliveryFailedEvent * containing the ID of the WhiteboardObject whose delivery has failed. */ public void whiteboardObjectDeliveryFailed ( WhiteboardObjectDeliveryFailedEvent evt) { String errorMessage = null; if (evt.getErrorCode() == WhiteboardObjectDeliveryFailedEvent.NETWORK_FAILURE) { errorMessage = "Network failure."; } else if (evt.getErrorCode() == WhiteboardObjectDeliveryFailedEvent .OFFLINE_MESSAGES_NOT_SUPPORTED) { errorMessage = "Offline messages aren't supported."; } else if (evt.getErrorCode() == WhiteboardObjectDeliveryFailedEvent .PROVIDER_NOT_REGISTERED) { errorMessage = "Protocol provider is not registered."; } else if (evt.getErrorCode() == WhiteboardObjectDeliveryFailedEvent .INTERNAL_ERROR) { errorMessage = "An internal error occured."; } else if (evt.getErrorCode() == WhiteboardObjectDeliveryFailedEvent .UNKNOWN_ERROR) { errorMessage = "An unknown error occured."; } String debugErrorMessage = "WBObjectDeliveryFailedEvent: The following object: " + evt.getSourceWhiteboardObject() + " has NOT been delivered to " + evt.getDestinationContact().getDisplayName() + " because of the following error: " + errorMessage; if (logger.isDebugEnabled()) logger.debug (debugErrorMessage); WhiteboardActivator.getUiService().getPopupDialog() .showMessagePopupDialog(errorMessage, "Error", PopupDialog.ERROR_MESSAGE); } /** * Returns the WhiteboardFrame associated with the Contact. * * @param c contact * @return WhiteboardFrame with the Contact or null (if nothing found) */ private WhiteboardFrame getWhiteboardFrame (WhiteboardSession session) { for (WhiteboardFrame whiteboardFrame : wbFrames) { if (whiteboardFrame.getWhiteboardSession().equals (session)) return whiteboardFrame; } return null; } /** * Returns the WhiteboardFrame associated with the Contact. * * @param c contact * @return WhiteboardFrame with the Contact or null (if nothing found) */ private WhiteboardFrame getWhiteboardFrame (Contact contact) { WhiteboardFrame whiteboardFrame = null; for(int i =0; i < wbFrames.size (); i++) { whiteboardFrame = wbFrames.get (i); if (whiteboardFrame.getContact() != null && whiteboardFrame.getContact().equals (contact)) return whiteboardFrame; } return null; } /** * Called when a deleted WhiteboardObject has been received. * * @param evt the WhiteboardObjectDeletedEvent containing * the identification of the deleted WhiteboardObject, its sender and * other details. */ public void whiteboardObjectDeleted (WhiteboardObjectDeletedEvent evt) { WhiteboardFrame wbf = getWhiteboardFrame ( evt.getSourceWhiteboardSession()); if(wbf == null) { return; } wbf.setVisible (true); String id = evt.getId (); wbf.receiveDeleteWhiteboardObject (id); } /** * Listens for WhiteboardInvitationReceivedEvents and shows a * dialog to the user, where she could accept, reject or ignore an * incoming invitation. */ private class InvitationListener implements WhiteboardInvitationListener { public void invitationReceived(WhiteboardInvitationReceivedEvent evt) { OperationSetWhiteboarding whiteboardOpSet = evt.getSourceOperationSet(); InvitationReceivedDialog dialog = new InvitationReceivedDialog( WhiteboardSessionManager.this, whiteboardOpSet, evt.getInvitation()); dialog.pack(); dialog.setLocation( Toolkit.getDefaultToolkit().getScreenSize().width/2 - dialog.getWidth()/2, Toolkit.getDefaultToolkit().getScreenSize().height/2 - dialog.getHeight()/2 ); dialog.setVisible(true); } } /** * Called to accept an incoming invitation. Adds the invitation chat room * to the list of chat rooms and joins it. * * @param invitation the invitation to accept. */ public void acceptInvitation(WhiteboardInvitation invitation) { WhiteboardSession whiteboard = invitation.getTargetWhiteboard(); byte[] password = invitation.getWhiteboardPassword(); try { if(password == null) whiteboard.join(); else whiteboard.join(password); } catch (OperationFailedException e) { WhiteboardActivator.getUiService().getPopupDialog() .showMessagePopupDialog( Resources.getString("failedToJoinWhiteboard", new String[] {whiteboard.getWhiteboardID()}), Resources.getString("service.gui.ERROR"), PopupDialog.ERROR_MESSAGE); logger.error("Failed to join whiteboard: " + whiteboard.getWhiteboardID(), e); } } /** * Rejects the given invitation with the specified reason. * * @param whiteboardOpSet the operation set to use for rejecting the * invitation * @param invitation the invitation to reject * @param reason the reason for the rejection */ public void rejectInvitation( OperationSetWhiteboarding whiteboardOpSet, WhiteboardInvitation invitation, String reason) { whiteboardOpSet.rejectInvitation(invitation, reason); } /** * Listens for presence events. */ private class PresenceListener implements WhiteboardSessionPresenceListener { /** * Implements the WhiteboardSessionPresenceListener * .whiteboardSessionPresenceChanged method. */ public void whiteboardSessionPresenceChanged( WhiteboardSessionPresenceChangeEvent evt) { WhiteboardSession whiteboardSession = evt.getWhiteboardSession(); if (evt.getEventType().equals( WhiteboardSessionPresenceChangeEvent.LOCAL_USER_JOINED)) { whiteboardSession.addWhiteboardObjectListener ( WhiteboardSessionManager.this); WhiteboardFrame frame = getWhiteboardFrame(evt.getWhiteboardSession()); if (frame == null) { frame = new WhiteboardFrame( WhiteboardSessionManager.this, whiteboardSession); frame.setVisible (true); wbFrames.add (frame); } } else if (evt.getEventType().equals( WhiteboardSessionPresenceChangeEvent.LOCAL_USER_JOIN_FAILED)) { WhiteboardActivator.getUiService().getPopupDialog() .showMessagePopupDialog ( Resources.getString("failedToJoinWhiteboard", new String[]{whiteboardSession.getWhiteboardID()}) + evt.getReason(), Resources.getString("service.gui.ERROR"), PopupDialog.ERROR_MESSAGE); } else if (evt.getEventType().equals( WhiteboardSessionPresenceChangeEvent.LOCAL_USER_LEFT)) { WhiteboardFrame frame = getWhiteboardFrame(whiteboardSession); if (frame == null) return; wbFrames.remove(frame); frame.dispose(); whiteboardSession.removeWhiteboardObjectListener( WhiteboardSessionManager.this); } else if (evt.getEventType().equals( WhiteboardSessionPresenceChangeEvent.LOCAL_USER_KICKED)) { } else if (evt.getEventType().equals( WhiteboardSessionPresenceChangeEvent.LOCAL_USER_DROPPED)) { } } } /** * Removes a white board frame. * * @param frame the frame to remove */ public void removeWhiteboardWindow(WhiteboardFrame frame) { synchronized (wbFrames) { wbFrames.remove(frame); } } }