### Eclipse Workspace Patch 1.0 #P org.eclipse.compare Index: compare/org/eclipse/compare/internal/patch/WorkspacePatcher.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/WorkspacePatcher.java,v retrieving revision 1.1 diff -u -r1.1 WorkspacePatcher.java --- compare/org/eclipse/compare/internal/patch/WorkspacePatcher.java 6 Oct 2005 17:18:00 -0000 1.1 +++ compare/org/eclipse/compare/internal/patch/WorkspacePatcher.java 24 Apr 2006 14:52:01 -0000 @@ -24,6 +24,7 @@ import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; @@ -32,6 +33,7 @@ import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.core.runtime.jobs.MultiRule; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Shell; @@ -265,10 +267,22 @@ public ISchedulingRule[] getTargetProjects() { List projects = new ArrayList(); + //Determine the appropriate scheduling rules for (int i = 0; i < fDiffProjects.length; i++) { DiffProject diffProject = fDiffProjects[i]; - projects.add(diffProject.getProject()); + IProject tempProject = diffProject.getProject(); + ISchedulingRule scheduleRule; + MultiRule multiRule = null; + // The goal here is to lock as little of the workspace as neccessary + // but still allow the patcher to obtain the locks it needs. + // As such, we need to get the modify rules from the rule factory for the .project file. A pessimistic + // rule factory will return the root, while others might return just the project. Combining + // this rule with the project will result in the smallest possible locking set. + scheduleRule = ResourcesPlugin.getWorkspace().getRuleFactory().modifyRule(tempProject.getFile(IProjectDescription.DESCRIPTION_FILE_NAME)); + multiRule = new MultiRule(new ISchedulingRule[]{scheduleRule, tempProject}); + projects.add(multiRule); } + return (ISchedulingRule[]) projects.toArray(new ISchedulingRule[projects.size()]); } Index: compare/org/eclipse/compare/internal/patch/PatchWizard.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.compare/compare/org/eclipse/compare/internal/patch/PatchWizard.java,v retrieving revision 1.28 diff -u -r1.28 PatchWizard.java --- compare/org/eclipse/compare/internal/patch/PatchWizard.java 28 Mar 2006 14:51:00 -0000 1.28 +++ compare/org/eclipse/compare/internal/patch/PatchWizard.java 24 Apr 2006 14:52:01 -0000 @@ -17,6 +17,7 @@ import org.eclipse.compare.internal.Utilities; import org.eclipse.compare.internal.patch.CompareWithPatchAction.PatchWizardDialog; import org.eclipse.core.resources.IResource; +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; @@ -103,11 +104,12 @@ // create scheduling rule based on the type of patch - single or workspace ISchedulingRule scheduleRule= null; if (fPatcher.isWorkspacePatch()) { - // workspace patch + // workspace patch scheduleRule= new MultiRule(fPatcher.getTargetProjects()); } else { // single patch - scheduleRule= getTarget(); + IResource resource = getTarget(); + scheduleRule= ResourcesPlugin.getWorkspace().getRuleFactory().modifyRule(resource); } WorkspaceModifyOperation op= new WorkspaceModifyOperation(scheduleRule) {