blob: 62a4f43762658f42185b433b94789ec6bda49a73 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 Remy Chi Jian Suen and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Remy Chi Jian Suen <remy.suen@gmail.com> - initial API and implementation
******************************************************************************/
package org.eclipse.ecf.internal.sync.ui.resources;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.util.ECFException;
import org.eclipse.ecf.datashare.IChannelContainerAdapter;
import org.eclipse.ecf.docshare2.DocShare;
import org.eclipse.ecf.internal.sync.resources.core.ResourcesShare;
import org.eclipse.ecf.internal.sync.resources.core.SyncResourcesCore;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IPageListener;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IWindowListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.statushandlers.StatusManager;
import org.eclipse.ui.texteditor.ITextEditor;
import org.osgi.framework.BundleContext;
public class SyncResourcesUI extends AbstractUIPlugin {
public static final String PLUGIN_ID = "org.eclipse.ecf.sync.ui.resources"; //$NON-NLS-1$
private static SyncResourcesUI instance;
private IWindowListener windowListener = new IWindowListener() {
public void windowOpened(IWorkbenchWindow window) {
window.addPageListener(pageListener);
}
public void windowDeactivated(IWorkbenchWindow window) {
// nothing to do
}
public void windowClosed(IWorkbenchWindow window) {
window.removePageListener(pageListener);
}
public void windowActivated(IWorkbenchWindow window) {
// nothing to do
}
};
private IPageListener pageListener = new IPageListener() {
public void pageOpened(IWorkbenchPage page) {
page.addPartListener(partListener);
}
public void pageClosed(IWorkbenchPage page) {
page.removePartListener(partListener);
}
public void pageActivated(IWorkbenchPage page) {
// nothing to do
}
};
private IPartListener partListener = new IPartListener() {
public void partOpened(IWorkbenchPart part) {
ITextEditor editor = (ITextEditor) part
.getAdapter(ITextEditor.class);
if (editor != null) {
IFile file = (IFile) editor.getEditorInput().getAdapter(
IFile.class);
if (file != null) {
startSharing(editor, file);
}
}
}
public void partDeactivated(IWorkbenchPart part) {
// nothing to do
}
public void partClosed(IWorkbenchPart part) {
ITextEditor editor = (ITextEditor) part
.getAdapter(ITextEditor.class);
if (editor != null) {
IFile file = (IFile) editor.getEditorInput().getAdapter(
IFile.class);
if (file != null) {
stopSharing(editor, file);
}
}
}
public void partBroughtToTop(IWorkbenchPart part) {
// nothing to do
}
public void partActivated(IWorkbenchPart part) {
// nothing to do
}
};
private Map sharedFiles = new HashMap();
private Map sharedEditors = new HashMap();
private boolean share(IFile file) {
IPath path = file.getFullPath();
Integer integer = (Integer) sharedFiles.get(path);
if (integer == null) {
sharedFiles.put(path, Integer.valueOf(1));
return true;
}
sharedFiles.put(path, Integer.valueOf(integer.intValue() + 1));
return false;
}
private boolean unshare(IFile file) {
IPath path = file.getFullPath();
Integer integer = (Integer) sharedFiles.remove(path);
if (integer == null) {
// if this file isn't being shared, will be null, return false
return false;
}
if (integer.intValue() == 1) {
return true;
}
sharedFiles.put(path, Integer.valueOf(integer.intValue() - 1));
return false;
}
private void startSharing(ITextEditor editor, IFile file) {
String projectName = file.getProject().getName();
for (Iterator it = SyncResourcesCore.getResourceShares().iterator(); it
.hasNext();) {
ResourcesShare share = (ResourcesShare) it.next();
if (share.isSharing(projectName) && share(file)) {
DocShare docShare = getDocShare(share.getContainerID());
try {
IAnnotationModel annotationModel = editor
.getDocumentProvider().getAnnotationModel(
editor.getEditorInput());
docShare.startSharing(share.getLocalID(), share
.getReceiverID(), file.getFullPath().toString(),
annotationModel);
ISelectionProvider provider = editor.getSelectionProvider();
if (provider instanceof IPostSelectionProvider) {
ISelectionChangedListener listener = new SelectionChangedListener(
share.getReceiverID(), file.getFullPath()
.toString(), docShare);
((IPostSelectionProvider) provider)
.addPostSelectionChangedListener(listener);
sharedEditors.put(editor, listener);
}
} catch (ECFException e) {
IStatus status = new Status(IStatus.ERROR, PLUGIN_ID,
"Could not send initiation request to " //$NON-NLS-1$
+ share.getReceiverID(), e);
log(status);
StatusManager.getManager().handle(status,
StatusManager.SHOW);
} catch (CoreException e) {
IStatus status = new Status(IStatus.ERROR, PLUGIN_ID,
"Could not connect to the file buffer of " //$NON-NLS-1$
+ file.getFullPath(), e);
log(status);
StatusManager.getManager().handle(status,
StatusManager.SHOW);
}
}
}
}
private void stopSharing(ITextEditor editor, IFile file) {
String projectName = file.getProject().getName();
for (Iterator it = SyncResourcesCore.getResourceShares().iterator(); it
.hasNext();) {
ResourcesShare share = (ResourcesShare) it.next();
if (share.isSharing(projectName) && unshare(file)) {
DocShare docShare = getDocShare(share.getContainerID());
stopSharing(docShare, share.getReceiverID(), editor, file);
}
}
}
private void stopSharing(DocShare share, ID id, ITextEditor editor,
IFile file) {
try {
share.stopSharing(id, file.getFullPath().toString());
} catch (ECFException e) {
log(new Status(IStatus.ERROR, PLUGIN_ID,
"Could not send stop message to " + id, e)); //$NON-NLS-1$
}
ISelectionChangedListener listener = (ISelectionChangedListener) sharedEditors
.remove(editor);
if (listener != null) {
ISelectionProvider provider = editor.getSelectionProvider();
if (provider instanceof IPostSelectionProvider) {
((IPostSelectionProvider) provider)
.removePostSelectionChangedListener(listener);
}
}
}
public SyncResourcesUI() {
instance = this;
}
public void start(BundleContext context) throws Exception {
super.start(context);
getWorkbench().addWindowListener(windowListener);
IWorkbenchWindow[] workbenchWindows = getWorkbench()
.getWorkbenchWindows();
for (int i = 0; i < workbenchWindows.length; i++) {
workbenchWindows[i].addPageListener(pageListener);
IWorkbenchPage[] pages = workbenchWindows[i].getPages();
for (int j = 0; j < pages.length; j++) {
pages[j].addPartListener(partListener);
}
}
}
public static SyncResourcesUI getDefault() {
return instance;
}
public Display getDisplay() {
return getWorkbench().getDisplay();
}
public static void log(IStatus status) {
instance.getLog().log(status);
}
public void stop(BundleContext context) throws Exception {
getWorkbench().removeWindowListener(windowListener);
IWorkbenchWindow[] workbenchWindows = getWorkbench()
.getWorkbenchWindows();
for (int i = 0; i < workbenchWindows.length; i++) {
workbenchWindows[i].removePageListener(pageListener);
IWorkbenchPage[] pages = workbenchWindows[i].getPages();
for (int j = 0; j < pages.length; j++) {
pages[j].removePartListener(partListener);
}
}
super.stop(context);
}
private static Map docshareChannels = new HashMap();
public static DocShare getDocShare(ID containerID) {
return (DocShare) docshareChannels.get(containerID);
}
public static DocShare addDocShare(ID containerID,
IChannelContainerAdapter channelAdapter) throws ECFException {
DocShare docShare = (DocShare) docshareChannels.get(containerID);
if (docShare == null) {
return (DocShare) docshareChannels.put(containerID,
new WorkbenchAwareDocShare(channelAdapter));
}
return docShare;
}
public static DocShare removeDocShare(ID containerID) {
return (DocShare) docshareChannels.remove(containerID);
}
public static ResourcesShare getResourceShare(ID containerID) {
return SyncResourcesCore.getResourcesShare(containerID);
}
public static ResourcesShare addResourceShare(ID containerID,
IChannelContainerAdapter channelAdapter) throws ECFException {
ResourcesShare resourcesShare = SyncResourcesCore
.getResourcesShare(containerID);
if (resourcesShare == null) {
resourcesShare = new WorkbenchAwareResourcesShare(containerID,
channelAdapter);
SyncResourcesCore.addResourcesShare(containerID, resourcesShare);
}
return resourcesShare;
}
public static ResourcesShare removeResourceShare(ID containerID) {
return SyncResourcesCore.removeResourcesShare(containerID);
}
private class SelectionChangedListener implements ISelectionChangedListener {
private ID targetID;
private String path;
private DocShare share;
public SelectionChangedListener(ID targetID, String path, DocShare share) {
this.targetID = targetID;
this.path = path;
this.share = share;
}
public void selectionChanged(SelectionChangedEvent e) {
ISelection selection = e.getSelection();
if (selection instanceof ITextSelection) {
ITextSelection textSelection = (ITextSelection) selection;
try {
share.sendSelection(targetID, path, textSelection
.getOffset(), textSelection.getLength());
} catch (ECFException exception) {
log(new Status(IStatus.ERROR, PLUGIN_ID,
"Could not send selection message to " + targetID, //$NON-NLS-1$
exception));
}
}
}
}
}