diff options
Diffstat (limited to 'bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs')
6 files changed, 494 insertions, 0 deletions
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RepositoryLocationSchedulingRule.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RepositoryLocationSchedulingRule.java new file mode 100644 index 000000000..94228114f --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RepositoryLocationSchedulingRule.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ccvs.ui.model; + +import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation; + +/** + * A simple job scheduling rule for serializing jobs for an ICVSRepositoryLocation + */ +public class RepositoryLocationSchedulingRule implements ISchedulingRule { + ICVSRepositoryLocation location; + public RepositoryLocationSchedulingRule(ICVSRepositoryLocation location) { + this.location = location; + } + public boolean isConflicting(ISchedulingRule rule) { + if(rule instanceof RepositoryLocationSchedulingRule) { + return ((RepositoryLocationSchedulingRule)rule).location.equals(location); + } + return false; + } + public boolean contains(ISchedulingRule rule) { + return isConflicting(rule); + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSBlockingRunnableContext.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSBlockingRunnableContext.java new file mode 100644 index 000000000..6b2fb3895 --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSBlockingRunnableContext.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ccvs.ui.operations; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.jface.operation.IRunnableContext; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.team.internal.ccvs.ui.Policy; +import org.eclipse.ui.PlatformUI; + +/** + * This CVS runnable context blocks the UI and can therfore have a shell assigned to + * it (since the shell won't be closed by the user before the runnable completes. + */ +public class CVSBlockingRunnableContext implements ICVSRunnableContext { + + private Shell shell; + private IRunnableContext runnableContext; + + public CVSBlockingRunnableContext(Shell shell) { + this.shell = shell; + } + + /** + * Run the given runnable in the context of the receiver. By default, the + * progress is provided by the active workbench windows but subclasses may + * override this to provide progress in some other way (Progress Monitor or + * job). + */ + public void run(String title, ISchedulingRule schedulingRule, boolean postponeBuild, IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException { + getRunnableContext().run(true /* fork */, true /* cancelable */, wrapRunnable(title, schedulingRule, postponeBuild, runnable)); + } + + protected IRunnableContext getRunnableContext() { + if (runnableContext == null) { + return PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + } + return runnableContext; + } + + /* + * Return an IRunnableWithProgress that sets the task name for the progress monitor + * and runs in a workspace modify operation if requested. + */ + private IRunnableWithProgress wrapRunnable(final String title, final ISchedulingRule schedulingRule, final boolean postponeBuild, final IRunnableWithProgress runnable) { + return new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + monitor.beginTask(title, 100); + try { + if (schedulingRule == null && !postponeBuild) { + runnable.run(Policy.subMonitorFor(monitor, 100)); + } else { + final Exception[] exception = new Exception[] { null }; + ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() { + public void run(IProgressMonitor pm) throws CoreException { + try { + runnable.run(pm); + } catch (InvocationTargetException e) { + exception[0] = e; + } catch (InterruptedException e) { + exception[0] = e; + } + } + }, schedulingRule, Policy.subMonitorFor(monitor, 100)); + if (exception[0] != null) { + if (exception[0] instanceof InvocationTargetException) { + throw (InvocationTargetException)exception[0]; + } else if (exception[0] instanceof InterruptedException) { + throw (InterruptedException)exception[0]; + } + } + } + } catch (CoreException e) { + throw new InvocationTargetException(e); + } finally { + monitor.done(); + } + } + }; + } + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.operations.CVSRunnableContext#getShell() + */ + public Shell getShell() { + return shell; + } + + /** + * Set the shell to be used by the owner of this context to prompt the user. + * @param shell + */ + public void setShell(Shell shell) { + this.shell = shell; + } + + /** + * @param runnableContext + */ + public void setRunnableContext(IRunnableContext runnableContext) { + this.runnableContext = runnableContext; + } + +} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSNonblockingRunnableContext.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSNonblockingRunnableContext.java new file mode 100644 index 000000000..dc8ee0e79 --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSNonblockingRunnableContext.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ccvs.ui.operations; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.core.resources.WorkspaceJob; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.IJobChangeListener; +import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.team.internal.ccvs.core.CVSException; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +/** + * This runnable context executes it's operation in the context of a background job. + */ +public class CVSNonblockingRunnableContext implements ICVSRunnableContext { + + private IJobChangeListener listener; + + public CVSNonblockingRunnableContext() { + this(null); + } + + public CVSNonblockingRunnableContext(IJobChangeListener listener) { + this.listener = listener; + } + + protected IStatus run(IRunnableWithProgress runnable, IProgressMonitor monitor) { + try { + runnable.run(monitor); + } catch (InvocationTargetException e) { + return CVSException.wrapException(e).getStatus(); + } catch (InterruptedException e) { + return Status.OK_STATUS; + } + return Status.OK_STATUS; + } + + protected Job getBasicJob(String title, final IRunnableWithProgress runnable) { + return new Job(title) { + public IStatus run(IProgressMonitor monitor) { + return CVSNonblockingRunnableContext.this.run(runnable, monitor); + } + }; + } + + protected Job getWorkspaceJob(String title, final IRunnableWithProgress runnable) { + return new WorkspaceJob(title) { + public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException { + return CVSNonblockingRunnableContext.this.run(runnable, monitor); + } + }; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.operations.ICVSRunnableContext#run(java.lang.String, boolean, org.eclipse.jface.operation.IRunnableWithProgress) + */ + public void run(String title, ISchedulingRule schedulingRule, boolean postponeBuild, IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException { + Job job; + if (schedulingRule == null && !postponeBuild) { + job = getBasicJob(title, runnable); + } else { + job = getWorkspaceJob(title, runnable); + if (schedulingRule != null) { + job.setRule(schedulingRule); + } + } + if (listener != null) { + job.addJobChangeListener(listener); + } + schedule(job); + } + + protected void schedule(Job job) { + job.schedule(); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.operations.ICVSRunnableContext#getShell() + */ + public Shell getShell() { + final Shell[] newShell = new Shell[] { null }; + Display.getDefault().syncExec( + new Runnable() { + public void run() { + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) { + Display display = Display.getDefault(); + newShell[0] = new Shell(display); + } else { + newShell[0] = window.getShell(); + } + } + }); + return newShell[0]; + } +} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSSubscriberNonblockingContext.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSSubscriberNonblockingContext.java new file mode 100644 index 000000000..f0cd4b5bb --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSSubscriberNonblockingContext.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ccvs.ui.operations; + +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.team.internal.ui.jobs.JobStatusHandler; +import org.eclipse.team.ui.sync.SubscriberAction; + +/** + * This context uses the JobStatusHandler from SubscriberAction to ensure + * proper busy indication in the sync view. + */ +public class CVSSubscriberNonblockingContext extends CVSNonblockingRunnableContext { + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.operations.CVSNonblockingRunnableContext#schedule(org.eclipse.core.runtime.jobs.Job) + */ + protected void schedule(Job job) { + JobStatusHandler.schedule(job, SubscriberAction.SUBSCRIBER_JOB_TYPE); + } + +} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/FetchMembersOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/FetchMembersOperation.java new file mode 100644 index 000000000..8f3de3dac --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/FetchMembersOperation.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ccvs.ui.operations; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.progress.IElementCollector; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.team.core.TeamException; +import org.eclipse.team.core.sync.IRemoteResource; +import org.eclipse.team.internal.ccvs.core.CVSException; +import org.eclipse.team.internal.ccvs.core.CVSTag; +import org.eclipse.team.internal.ccvs.core.ICVSFile; +import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder; +import org.eclipse.team.internal.ccvs.core.ICVSRemoteResource; +import org.eclipse.team.internal.ccvs.core.resources.RemoteFolder; +import org.eclipse.team.internal.ccvs.core.resources.RemoteFolderMemberFetcher; +import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; +import org.eclipse.team.internal.ccvs.ui.Policy; + +/** + * Fetch the members of a remote folder in the background, passing incremental + * results through an IElementCollector. + */ +public class FetchMembersOperation extends RemoteOperation { + + /* internal uzse only */ IElementCollector collector; + /* internal uzse only */ RemoteFolderFilter filter = new RemoteFolderFilter(); + + public static class RemoteFolderFilter { + public ICVSRemoteResource[] filter(ICVSRemoteResource[] resource) { + return resource; + } + } + + public class InternalRemoteFolderMemberFetcher extends RemoteFolderMemberFetcher { + long sendIncrement = 100; + List unsent = new ArrayList(); + long intervalStart; + protected InternalRemoteFolderMemberFetcher(RemoteFolder parentFolder, CVSTag tag) { + super(parentFolder, tag); + } + protected void parentDoesNotExist() { + super.parentDoesNotExist(); + // Indicate that there are no children + collector.add(new Object[0], getProgressMonitor()); + } + protected RemoteFolder recordFolder(String name) { + RemoteFolder folder = super.recordFolder(name); + unsent.add(folder); + if (isTimeToSend()) { + sendFolders(); + } + return folder; + } + private boolean isTimeToSend() { + long currentTime = System.currentTimeMillis(); + return (currentTime - intervalStart) > sendIncrement; + } + protected IStatus performUpdate(IProgressMonitor progress, CVSTag tag) throws CVSException { + intervalStart = System.currentTimeMillis(); + IStatus status = super.performUpdate(progress, tag); + sendFolders(); + return status; + } + protected void updateFileRevisions(ICVSFile[] files, IProgressMonitor monitor) throws CVSException { + super.updateFileRevisions(files, monitor); + sendFiles(); + } + private void sendFolders() { + updateParentFolderChildren(); + collector.add(filter.filter((ICVSRemoteFolder[]) unsent.toArray(new ICVSRemoteFolder[unsent.size()])), getProgressMonitor()); + unsent.clear(); + intervalStart = System.currentTimeMillis(); + } + private void sendFiles() { + collector.add(getFiles(), getProgressMonitor()); + unsent.clear(); + } + private IProgressMonitor getProgressMonitor() { + return null; + } + } + + public FetchMembersOperation(Shell shell, ICVSRemoteFolder folder, IElementCollector collector) { + super(shell, new ICVSRemoteResource[] { folder }); + this.collector = collector; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#execute(org.eclipse.core.runtime.IProgressMonitor) + */ + protected void execute(IProgressMonitor monitor) throws CVSException, InterruptedException { + ICVSRemoteFolder remote = getRemoteFolder(); + if (remote.getClass().equals(RemoteFolder.class)) { + monitor = Policy.monitorFor(monitor); + boolean isRoot = remote.getName().equals(ICVSRemoteFolder.REPOSITORY_ROOT_FOLDER_NAME); + monitor.beginTask(null, 100 + (isRoot ? 30 : 0)); + RemoteFolderMemberFetcher fetcher = new InternalRemoteFolderMemberFetcher((RemoteFolder)remote, remote.getTag()); + fetcher.fetchMembers(Policy.subMonitorFor(monitor, 100)); + if (isRoot) { + ICVSRemoteResource[] modules = CVSUIPlugin.getPlugin() + .getRepositoryManager() + .getRepositoryRootFor(remote.getRepository()) + .getDefinedModules(remote.getTag(), Policy.subMonitorFor(monitor, 25)); + collector.add(filter.filter(modules), Policy.subMonitorFor(monitor, 5)); + } + } else { + monitor = Policy.monitorFor(monitor); + try { + monitor.beginTask(null, 100); + IRemoteResource[] children = remote.members(Policy.subMonitorFor(monitor, 95)); + collector.add(children, Policy.subMonitorFor(monitor, 5)); + } catch (TeamException e) { + throw CVSException.wrapException(e); + } finally { + monitor.done(); + } + } + + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#getTaskName() + */ + protected String getTaskName() { + return Policy.bind("FetchMembersOperation.0", getRemoteFolder().getName()); //$NON-NLS-1$ + } + + private ICVSRemoteFolder getRemoteFolder() { + return (ICVSRemoteFolder)getRemoteResources()[0]; + } + + public RemoteFolderFilter getFilter() { + return filter; + } + + public void setFilter(RemoteFolderFilter filter) { + this.filter = filter; + } + +} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ICVSRunnableContext.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ICVSRunnableContext.java new file mode 100644 index 000000000..64adcea1c --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ICVSRunnableContext.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ccvs.ui.operations; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.swt.widgets.Shell; + +/** + * An ICVSRunnableContext is used to provide the context for a CVS operation. + * The hierarchy of contexts is used to configure the following: + * 1) whether the operation is run in the background as a job + * 2) whether the operation modifies the workspace + * 3) what shell the operation should use to display info to the user + */ +public interface ICVSRunnableContext { + + /** + * Run the given runnable in the context of the receiver. By default, the + * progress is provided by the active workbench windows but subclasses may + * override this to provide progress in some other way (Progress Monitor or + * job). + */ + public abstract void run( + String title, + ISchedulingRule schedulingRule, + boolean postponeBuild, + IRunnableWithProgress runnable) + throws InvocationTargetException, InterruptedException; + + /** + * Get a shell that can be used to prompt the user. + * @return a shell + */ + public abstract Shell getShell(); +}
\ No newline at end of file |