Take a look at org.eclipse.wst.common.tests.ProjectUtility in the 
org.eclipse.wst.common.tests plugin.  There is a method in there for 
deleting projects as well.

Thank you,

Jason A. Sholl
[EMAIL PROTECTED]
919-543-0011 (t/l 441-0011)





"Mitov, Kiril" <[EMAIL PROTECTED]> 
Sent by: [EMAIL PROTECTED]
02/01/2008 07:47 AM
Please respond to
"General discussion of project-wide or architectural issues." 
<[email protected]>


To
"General discussion of project-wide or architectural issues." 
<[email protected]>
cc

Subject
RE: [wtp-dev] JUnit tip: How to delete projects






When it comes to deleting files I have once implemented this method
 
private void deleteFileAndUpdate(IFile file) throws Exception {
            ChangeListenerWithSemaphore listener = new 
ChangeListenerWithSemaphore(1);
            ResourcesPlugin.getWorkspace
().addResourceChangeListener(listener, IResourceChangeEvent.POST_CHANGE);
            int retries = 3;
            while (retries > 0) {
                  try {
                        deleteFile(file);
                        if (listener.waitForEvents()) {
                              retries = 0;
                              break;
                        }
                  } catch (CoreException e) {
                      ... more core here... see in the description.
                  } finally {
                        retries--;
                  }
            }
            assertTrue(retries == -1);
            ResourcesPlugin.getWorkspace
().removeResourceChangeListener(listener);
      }
 
The basic idea here is that you have not deleted a file/folder/project 
until you receive a ResourceChangeEvent for the deletion.
Since the event might be in the same thread or in another thread it is 
important to stop the current thread until an event occurs. This is what I 
am doing here. This has also worked for folders and projects. The 
listener.waitForEvents() is blocking the current thread until a 
notification for the deletion is received. In general the thread is 
blocked until the specified number of events (the number in the 
constructor of ChangeListenerWithSemaphore) is reached. But this can 
easily be changed to an another logic.
 
Here the "retires" are the number of failiers that I am willing to accept. 
In the catch(CoreException e) there is a special logic. If the message of 
the exception is "The requested operation cannot be performed on a file 
with a user-mapped section open" the code of the catch block is:
 
                        /*
                         * An exception was occurring - "The requested 
operation cannot
                         * be performed on a file with a user-mapped 
section open".
                         * Running the finalization as suggested at
                         * 
http://webteam.archive.org/jira/browse/HER-661?decorator=printable
                         */
                        System.runFinalization();
                        System.gc();
But I was unable to investigate the error more deeply.
The deleteFile method is:
protected static boolean deleteFile(final IFile file) throws Exception {
            ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
                  public void run(IProgressMonitor monitor) throws 
CoreException {
                        file.delete(false, monitor);
                  }
            }, monitor);
            return true;
}
 
The code of ChangeListenerWithSemaphore is
/**
 * This change listener will release a semaphore after the resource 
changed
 * method is called. For every resourceChanged call one release will be 
called.
 * 
 * @author Kiril Mitov [EMAIL PROTECTED]
 * 
 */
public final class ChangeListenerWithSemaphore implements 
IResourceChangeListener {
      private final Semaphore s;
      private final List<Object> deltas;
      private final int expectedEvents;
      private final List<IResourceChangeEvent> receivedEvents;
 
      public ChangeListenerWithSemaphore(int expectedEvents) throws 
InterruptedException {
            this.expectedEvents = expectedEvents;
            this.s = new Semaphore(1);
            this.s.acquire();
            this.deltas = Collections.synchronizedList(new 
LinkedList<Object>());
            this.receivedEvents = Collections.synchronizedList(new 
LinkedList<IResourceChangeEvent>());
      }
 
      public synchronized void resourceChanged(IResourceChangeEvent event) 
{
            receivedEvents.add(event);
            if (receivedEvents.size() > expectedEvents)
                  throw new IllegalStateException("The expected events 
were already reached");
            try {
                  deltas.add(event.getDelta());
            } catch (Exception e) {
                  Activator.getDefault().getLog().log(new Status(IStatus.
ERROR, Activator.PLUGIN_ID, e.getMessage(), e));
                  return;
            } finally {
                  if (expectedEvents == receivedEvents.size())
                        s.release();
            }
      }
 
      public boolean waitForEvents() throws InterruptedException {
            return s.tryAcquire(5, TimeUnit.SECONDS);
      }
 
      public synchronized List<Object> getDeltas() {
            return deltas;
      }
 
      public synchronized int getEvents() {
            return receivedEvents.size();
      }
 
      public List<IResourceChangeEvent> getReceivedEvents() {
            return receivedEvents;
      }
}
This is how I am creating, deleting and updating files. 
 
Best Regards,
Kiril
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On 
Behalf Of David M Williams
Sent: Friday, 1. February 2008 10:16
To: [email protected]
Subject: [wtp-dev] JUnit tip: How to delete projects


Some of our JUnits suites require that projects or other resources be 
deleted during the test, for various reasons, and I think some of the 
"random errors" we see are because it's hard to delete a project, or file, 
in a multi-threaded Eclipse. If there is a file from the project open in 
another thread, for example, perhaps in a thread that's running 
validation, hence reading files, the delete will fail ("randomly") and 
then that might cause a JUnit test to fail, directly or indirectly (by 
having an unexpected state). 

I had to solve this, just this evening, and took me a while, reading 
platform test examples, and googling around, to find a solution that I 
think is fairly good ... for JUnit tests, at least. 

I've pasted the code below ... just in case it helps anyone. Hopefully the 
constants are obvious, but if anyone wants to see the whole class, it is 
org.eclipse.jst.jsp.core.tests.taglibindex.TestIndex 

And ... as always the case in open development ... if anyone has other 
tips/tricks, or better ways, feel free to let us know. 

Thanks, 




        /** 
         * It's not easy to delete projects. If any of it's files are open 
by another thread, 
         * the operation will fail. So, this method will make several 
attempts before giving up. 
         * @param project 
         * @throws CoreException 
         * @throws InterruptedException 
         */ 
        private void deleteProject(IProject project) throws CoreException, 
InterruptedException { 
                int nTrys = 0; 
                while (project != null && project.exists() && nTrys < 
MAX_RETRYS) { 
                        try { 
                                nTrys++; 
                                project.delete(true, true, null); 
                        } 
                        catch (ResourceException e) { 
                                if (DEBUG) { 
                                        System.out.println(); 
                                        System.out.println("Could not 
delete project on attempt number: "+ nTrys); 
                                        IStatus eStatus = e.getStatus(); 
                                        // should always be MultiStatus, 
but we'll check 
                                        if (eStatus instanceof 
MultiStatus) { 
                                                MultiStatus mStatus = 
(MultiStatus) eStatus; 
                                                IStatus[] iStatus = 
mStatus.getChildren(); 
                                                for (int j = 0; j < 
iStatus.length; j++) { 
                                                        System.out
.println("Status: " + j + " " + iStatus[j]); 
                                                } 
                                        } 
                                        else { 
                                                System.out.println(
"Status: " + eStatus); 
                                        } 
                                } 
                                /* 
                                 * If we could not delete the first time, 
wait a bit and 
                                 * re-try. If we could not delete, it is 
likely because 
                                 * another thread has a file open, or 
similar (such as the 
                                 * validation thread). 
                                 */ 
                                Thread.sleep(PAUSE_TIME); 
                        } 
                } 
 
                if (project != null && project.exists()) { 
                        fail("Error in test infrastructure. Could not 
delete project " + project + " after " + MAX_RETRYS + "attempts."); 
                } 
        }_______________________________________________
wtp-dev mailing list
[email protected]
https://dev.eclipse.org/mailman/listinfo/wtp-dev

_______________________________________________
wtp-dev mailing list
[email protected]
https://dev.eclipse.org/mailman/listinfo/wtp-dev

Reply via email to