Package org.codemap.communication

Source Code of org.codemap.communication.SelectionShare

package org.codemap.communication;

import java.util.Collection;

import org.codemap.CodemapCore;
import org.codemap.MapSelection;
import org.codemap.communication.messages.Message;
import org.codemap.communication.messages.SelectionMessage;
import org.codemap.communication.messages.StartMessage;
import org.codemap.communication.messages.StopMessage;
import org.codemap.communication.util.EditorPartListener;
import org.codemap.util.Log;
import org.eclipse.core.runtime.Assert;
import org.eclipse.ecf.core.IContainer;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.util.ECFException;
import org.eclipse.ecf.datashare.AbstractShare;
import org.eclipse.ecf.datashare.IChannelContainerAdapter;
import org.eclipse.ecf.datashare.events.IChannelDisconnectEvent;
import org.eclipse.ecf.presence.IPresenceContainerAdapter;
import org.eclipse.ecf.presence.roster.IRoster;
import org.eclipse.ecf.presence.roster.IRosterEntry;
import org.eclipse.ecf.presence.roster.IRosterItem;
import org.eclipse.ecf.presence.roster.IRosterListener;
import org.eclipse.ecf.presence.roster.IRosterManager;
import org.eclipse.ecf.sync.IModelSynchronizationStrategy;
import org.eclipse.ecf.sync.SerializationException;
import org.eclipse.ecf.sync.doc.IDocumentSynchronizationStrategyFactory;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbenchPage;


public class SelectionShare extends AbstractShare {
   
    IRosterListener rosterListener = new IRosterListener() {
        public void handleRosterEntryAdd(IRosterEntry entry) {
            // nothing to do
        }

        public void handleRosterEntryRemove(IRosterEntry entry) {
            // nothing to do
        }
       
        /**
         * handle changes to the roster.
         * AFAIK: this might be a local or a remote disconnect.
         */
        public void handleRosterUpdate(IRoster roster, IRosterItem changedValue) {
             if (!(changedValue instanceof IRosterEntry)) return;
            
             IRosterEntry rosterEntry = (IRosterEntry) changedValue;
             System.out.println(rosterEntry);
             ID changedID = rosterEntry.getUser().getID();
             String message = null;
            
             synchronized (SelectionShare.this) {
                if (changedID.equals(ourID)) {
                    localStopShare();
                    message = "Sharing aborted locally.";
                }
                else if (changedID.equals(remoteID)) {
                    localStopShare();
                    message = "Sharing aborted remotely.";
                }
            }
            if (message != null) showStopShareMessage(message);               
        }
    };
   
    private IModelSynchronizationStrategy syncStrategy;
    private IDocumentSynchronizationStrategyFactory factory;
    private IRosterManager rosterManager;

    private ID ourID;
    private ID remoteID;

    private EditorPartListener listener;   

    public SelectionShare(IChannelContainerAdapter adapter) throws ECFException {
        super(adapter);
        factory = ECFContribution.getDefault().getColaSynchronizationStrategyFactory();
    }

    @Override
    protected void handleMessage(ID fromContainerID, byte[] data) {
        Message message;
        try {
            message = Message.deserialize(data);
            Assert.isNotNull(message);
            message.applyOn(this);
        } catch (SerializationException e) {
            Log.error(e);
        }
    }
   
    @Override
    protected void handleDisconnectEvent(IChannelDisconnectEvent cde) {
        boolean weDisconnected = (ourID != null && ourID.equals(cde.getTargetID()));
        boolean wasSharing = isSharing();
        // Stop things and *then* notify user
        localStopShare();
        if (wasSharing) {
            // TODO: use some more verbose messages (check whole file ...)
            if (weDisconnected) showStopShareMessage("We stopped sharing.");
            else showStopShareMessage("Remote stopped sharing.");
        }
    }   

    protected boolean openReceiverDialog(ID sender) {
        return MessageDialog.openQuestion(null, "Share your Selection.", "Do you want to share your Codemap selection with " + sender.getName() + "?");
    }
   
    protected void showStopShareMessage(final String message) {
        final Display display = Display.getDefault();
        display.asyncExec(new Runnable() {
            public void run() {
                MessageDialog.openInformation(display.getActiveShell(), "Stopped sharing.", message);
            }
        });              
    }   

    /**
     * Called when we are on the remote side.
     */
    public synchronized void handleStartRequest(final Message message) {
        remoteID = message.senderID;
        Assert.isNotNull(remoteID);
        ourID = message.receiverID;
        Assert.isNotNull(ourID);
       
        // execute async to avoid nested monitor in callbacks
        Display.getDefault().asyncExec(new Runnable(){
            @Override
            public void run() {
                synchronized(SelectionShare.this) {
                    if (openReceiverDialog(message.senderID)) {
                        // SYNC API. Create an instance of the synchronization strategy on
                        // the receiver
                        syncStrategy = createSynchronizationStrategy(false);
                        Assert.isNotNull(syncStrategy);
                        addEditorListener();           
                    } else {
                        sendStopMessage();
                        localStopShare();
                    }                   
                }
            }
        });
    }

    /**
     * Add a listener that notifies us when the files are opened/closed in an
     * editor.
     */
    private void addEditorListener() {
        // needs to run in an UI Thread to have access to the workbench.
        if (listener == null) {
            listener = new EditorPartListener(SelectionShare.this);
        }
       
        Display.getDefault().asyncExec(new Runnable() {
            @Override
            public void run() {
                // needs to run in an UI Thread to have access to the workbench.             
                IWorkbenchPage page = CodemapCore.getPlugin().getWorkbench().getActiveWorkbenchWindow().getActivePage();
                page.addPartListener(listener);
            }
        });
    }

    public synchronized boolean isSharing() {
        return this.remoteID != null;
    }

    public synchronized void startShare(final ID our, final ID remote) {
        Assert.isNotNull(our);
        ourID = our;

        Assert.isNotNull(remote);
        remoteID = remote;

        syncStrategy = createSynchronizationStrategy(true);
        Assert.isNotNull(syncStrategy);
       
        sendMessageToRemote(new StartMessage(ourID, remoteID));
        localStartShare(getLocalRosterManager());
    }

    private void localStartShare(IRosterManager localRosterManager) {
        this.rosterManager = localRosterManager;
        if (this.rosterManager != null) {
            this.rosterManager.addRosterListener(rosterListener);
        }
        addEditorListener();
    }

    private IRosterManager getLocalRosterManager() {
        IContainer container = (IContainer) this.adapter.getAdapter(IContainer.class);
        if (container != null) {
            IPresenceContainerAdapter presenceContainerAdapter = (IPresenceContainerAdapter) container
                    .getAdapter(IPresenceContainerAdapter.class);
            if (presenceContainerAdapter != null) {
                return presenceContainerAdapter.getRosterManager();
            }
        }
        return null;
    }

    private IModelSynchronizationStrategy createSynchronizationStrategy(boolean isInitiator) {
        // Instantiate the service
        Assert.isNotNull(factory);
        return factory.createDocumentSynchronizationStrategy(getChannel().getID(), isInitiator);
    }

    public synchronized void onLocalSelectionChanged(Collection<String> selection) {
        sendMessageToRemote(new SelectionMessage(ourID, remoteID, selection));
    }

    public synchronized String getRemoteName() {
        if (remoteID == null)
            return "";
        return remoteID.getName();
    }

    public synchronized void stopShare() {
        sendStopMessage();
        localStopShare();
    }

    private void sendStopMessage() {
        sendMessageToRemote(new StopMessage(remoteID, ourID));
    }

    private void localStopShare() {
        getSelection().clear();
        ourID = null;
        remoteID = null;
        syncStrategy = null;   
    }

    private void sendMessageToRemote(Message message) {
        try {
            sendMessage(remoteID, message.serialize());
        } catch (SerializationException e) {
            Log.error(e);
        } catch (ECFException e) {
            Log.error(e);
        }
    }

    public synchronized void handleRemoteStop(StopMessage stopMessage) {
        getSelection().clear();
        ourID = null;
        remoteID = null;
        syncStrategy = null;
        removeEditorListener();
        showStopShareMessage("The remote User stopped sharing.");       
    }

    private void removeEditorListener() {
      if (listener == null) return;
        Display.getDefault().syncExec(new Runnable() {
            @Override
            public void run() {
                IWorkbenchPage page = CodemapCore.getPlugin().getWorkbench().getActiveWorkbenchWindow().getActivePage();
                page.removePartListener(listener);
            }
        });
    }

    public synchronized void handleRemoteSelection(Collection<String> selection) {
        getSelection().replaceAll(selection);
    }

    private MapSelection getSelection() {
        return ECFContribution.getDefault().getCommunicationSelection();
    }
}
TOP

Related Classes of org.codemap.communication.SelectionShare

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.