Neel
Neel

Reputation: 2100

refreshLocal on IResource throws exception

I am trying to programmatically refresh a folder inside the project for my Eclipse plugin. I have also included a simple semaphore rule in the Job. Here is the code:

public class MutexRule implements ISchedulingRule {
    public boolean isConflicting(ISchedulingRule rule) {
        return rule == this;
    }
    public boolean contains(ISchedulingRule rule) {
        return rule == this;
    }
}
...

Job refreshJob = new Job("Refreshing...") {

    public void run() {
        IResource myFolder = ...
        if(myFolder != null)
            myFolder.refreshLocal(DEPTH_INFINITE, null);
    }
};
refreshJob.setRule(

When I schedule two jobs, and run the refresh, I get the following exception:

Attempted to beginRule: P/test, does not match outer scope rule: ...

What am I missing? What is a possible solution / workaround?

Upvotes: 0

Views: 189

Answers (1)

greg-449
greg-449

Reputation: 111216

The error you are getting is because the IResource you are refreshing also has a scheduling rule (IResource implements ISchedulingRule). When there are nested scheduling rules the outer rule must 'contain' the inner rule - your MutexRule doesn't do this.

Because the resource already has a scheduling rule there is no need to set a rule on your job.

refreshLocal does not have to in a Job but if it is run from the UI thread a progress monitor should be provided using IProgressService or similar.

Update: refreshLocal can generate many resource changed events, to minimize these use a WorkspaceModifyOperation or a WorkspaceJob:

Job job = new WorkspaceJob("Refreshing") {

   public IStatus runInWorkspace(IProgressMonitor monitor) {
      monitor.beginTask("", IProgressMonitor.UNKNOWN);          

      try {
        resource.refreshLocal(monitor);
      }
      finally {
        monitor.done();
      }

      return Status.OK_STATUS;
   }
});

or

WorkspaceModifyOperation op = new WorkspaceModifyOperation() {

    @Override
    protected void execute(IProgressMonitor monitor) throws CoreException {

      resource.refreshLocal(monitor);

    }
};

If you are in a wizard page you can run the WorkspaceModifyOperation with:

getContainer().run(true, true, op);

elsewhere you can use:

IProgressService service = PlatformUI.getWorkbench().getProgressService();

service.run(true, true, op);

Even better is to use the Eclipse IFile and IFolder APIs to create files and folders, in this case refreshLocal is not required.

Upvotes: 2

Related Questions