blob: 4c8c6dfeac7b983bc5ca724613197dd49c86f369 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2004 IBM Corporation 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.team.examples.pessimistic;
import java.util.*;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.ui.*;
import org.eclipse.ui.dialogs.CheckedTreeSelectionDialog;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.views.navigator.ResourceSorter;
/**
* The <code>ResourceChangeListener</code> listens for resource changes
* and (optionally) prompts the user to add the new resources to the
* control of the repository provider.
*/
public class ResourceChangeListener implements IResourceDeltaVisitor, IResourceChangeListener {
/*
* Set of added resources
*/
private Set fAdded;
/*
* Set of removed resources
*/
private Set fRemoved;
public ResourceChangeListener() {
fAdded= new HashSet(1);
fRemoved= new HashSet(1);
}
/**
* Looks for the following changes:
* <ul>
* <li>Resources that are controlled and are removed</li>
* <li>Resources that are added under a managed project</li>
* </ul>
* @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(IResourceDelta)
*/
public boolean visit(IResourceDelta delta) throws CoreException {
IResource resource= delta.getResource();
if (resource != null) {
IProject project= resource.getProject();
if (project != null) {
PessimisticFilesystemProvider provider= (PessimisticFilesystemProvider)RepositoryProvider.getProvider(project, PessimisticFilesystemProviderPlugin.NATURE_ID);
if (provider == null)
return false;
if (provider.isControlled(resource)) {
switch (delta.getKind()) {
case IResourceDelta.CHANGED:
case IResourceDelta.ADDED:
return true;
case IResourceDelta.REMOVED:
fRemoved.add(resource);
return false;
}
} else {
switch (delta.getKind()) {
case IResourceDelta.CHANGED:
case IResourceDelta.REMOVED:
return true;
case IResourceDelta.ADDED:
// don't prompt for ignored resources
if (!provider.isIgnored(resource)) {
fAdded.add(resource);
}
return true;
}
}
} else {
return true;
}
}
return false;
}
/*
* Convenience method to return a resource array from a collection
*/
private IResource[] toResourceArray(Collection collection) {
if (collection.isEmpty()) {
return new IResource[0];
}
IResource[] resources= new IResource[collection.size()];
collection.toArray(resources);
return resources;
}
/**
* @see IResourceChangeListener#resourceChanged(IResourceChangeEvent)
*/
public void resourceChanged (IResourceChangeEvent event) {
try {
event.getDelta().accept(this);
} catch (CoreException e) {
e.printStackTrace();
PessimisticFilesystemProviderPlugin.getInstance().logError(e, "Exceptions during resource callback");
}
if (!fRemoved.isEmpty() || !fAdded.isEmpty()) {
final IWorkspaceRunnable workspaceRunnable= new IWorkspaceRunnable() {
public void run(final IProgressMonitor monitor) throws CoreException {
if (!fRemoved.isEmpty()) {
remove(monitor);
}
if (!fAdded.isEmpty()) {
add(monitor);
}
}
};
// must fork since we are in resource callback.
Runnable run= new Runnable() {
public void run() {
try {
IWorkspace workspace= ResourcesPlugin.getWorkspace();
if (workspace != null) {
workspace.run(workspaceRunnable, null);
}
} catch (CoreException e) {
PessimisticFilesystemProviderPlugin.getInstance().logError(e, "Problems encountered during attempt to add/remove control.");
}
}
};
new Thread(run).start();
}
}
/*
* Convenience method to get the preference for what to do
* when new resource have been detected.
*/
private int getAddToControlPreference() {
Preferences preferences= PessimisticFilesystemProviderPlugin.getInstance().getPluginPreferences();
return preferences.getInt(IPessimisticFilesystemConstants.PREF_ADD_TO_CONTROL);
}
/*
* Adds the resources to the control of the provider.
* If the add to control preference is:
* do nothing - does not add
* automatic - adds all resources
* prompt - brings up a prompt which requests that the user
* select which resources to add
*/
private void add(final IProgressMonitor monitor) {
switch (getAddToControlPreference()) {
case IPessimisticFilesystemConstants.OPTION_DO_NOTHING:
break;
case IPessimisticFilesystemConstants.OPTION_AUTOMATIC:
addToControl(fAdded, monitor);
break;
case IPessimisticFilesystemConstants.OPTION_PROMPT:
final Shell shell= getShell();
if (shell != null && !shell.isDisposed()) {
final Set resources= new HashSet(fAdded);
Runnable run= new Runnable() {
public void run() {
CheckedTreeSelectionDialog dialog= new CheckedTreeSelectionDialog(shell, new WorkbenchLabelProvider(), new ResourceSetContentProvider(resources));
dialog.setMessage("Select the resources to be added to the control of the repository.");
dialog.setTitle("Add resources to control");
dialog.setContainerMode(true);
dialog.setBlockOnOpen(true);
dialog.setSorter(new ResourceSorter(ResourceSorter.NAME));
Object[] resourceArray= resources.toArray();
dialog.setExpandedElements(resourceArray);
dialog.setInitialSelections(resourceArray);
dialog.setInput(ResourcesPlugin.getWorkspace().getRoot());
int status= dialog.open();
if (status == Window.OK) {
Object[] results= dialog.getResult();
if (results != null) {
Set resources= new HashSet(results.length);
for (int i= 0; i < results.length; i++) {
resources.add(results[i]);
}
addToControl(resources, monitor);
}
}
}
};
Display display= shell.getDisplay();
display.asyncExec(run);
} else {
PessimisticFilesystemProviderPlugin.getInstance().logError(null, "Could not aquire a shell");
}
break;
}
fAdded.clear();
}
/*
* Adds the resources to the control of the provider.
*/
private void addToControl(Collection resources, final IProgressMonitor monitor) {
Map byProject= sortByProject(resources);
for (Iterator i= byProject.keySet().iterator(); i.hasNext();) {
IProject project= (IProject) i.next();
PessimisticFilesystemProvider provider= (PessimisticFilesystemProvider)RepositoryProvider.getProvider(project, PessimisticFilesystemProviderPlugin.NATURE_ID);
if (provider != null) {
provider.addToControl(toResourceArray((Collection)byProject.get(project)), monitor);
}
}
}
/*
* Removes the resources from the control of the provider.
*/
private void remove(IProgressMonitor monitor) {
Map byProject= sortByProject(fRemoved);
for (Iterator i= byProject.keySet().iterator(); i.hasNext();) {
IProject project= (IProject) i.next();
PessimisticFilesystemProvider provider= (PessimisticFilesystemProvider)RepositoryProvider.getProvider(project, PessimisticFilesystemProviderPlugin.NATURE_ID);
if (provider != null) {
provider.removeFromControl(toResourceArray((Collection)byProject.get(project)), monitor);
}
}
fRemoved.clear();
}
/*
* Convenience method to sort the resources by project
*/
private Map sortByProject(Collection resources) {
Map byProject= new HashMap();
for (Iterator i= resources.iterator(); i.hasNext();) {
IResource resource= (IResource) i.next();
IProject project= resource.getProject();
Set set= (Set)byProject.get(project);
if (set == null) {
set= new HashSet(1);
byProject.put(project, set);
}
set.add(resource);
}
return byProject;
}
/*
* Convenience method which answers a shell with which to prompt.
*/
private Shell getShell() {
IWorkbench workbench= PlatformUI.getWorkbench();
if (workbench != null) {
IWorkbenchWindow window= workbench.getActiveWorkbenchWindow();
if (window == null) {
IWorkbenchWindow[] windows= workbench.getWorkbenchWindows();
if (windows != null && windows.length > 0) {
window= windows[0];
}
}
if (window != null) {
Shell shell= window.getShell();
if (shell == null)
return null;
if (shell.isDisposed())
return null;
return shell;
}
}
return null;
}
/**
* Starts listening for changes.
*/
public void startup() {
ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE);
if (PessimisticFilesystemProviderPlugin.getInstance().isDebugging())
System.out.println ("Resource callback registered");
}
/**
* Stops listening for changes.
*/
public void shutdown() {
ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
if (PessimisticFilesystemProviderPlugin.getInstance().isDebugging())
System.out.println ("Resource callback unregistered");
}
}