/******************************************************************************* | |
* Copyright (c) 2009 by SAP AG, Walldorf. | |
* 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: | |
* SAP AG - initial API and implementation | |
*******************************************************************************/ | |
package org.eclipse.jst.ws.jaxws.testutils.jobs; | |
import java.lang.reflect.InvocationTargetException; | |
import org.eclipse.core.resources.IWorkspace; | |
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.IStatus; | |
import org.eclipse.core.runtime.NullProgressMonitor; | |
import org.eclipse.core.runtime.Platform; | |
import org.eclipse.core.runtime.Status; | |
import org.eclipse.core.runtime.jobs.Job; | |
import org.eclipse.jdt.core.IJavaElement; | |
import org.eclipse.jdt.core.JavaModelException; | |
import org.eclipse.jdt.core.search.IJavaSearchConstants; | |
import org.eclipse.jdt.core.search.SearchEngine; | |
import org.eclipse.jdt.core.search.SearchPattern; | |
import org.eclipse.jdt.core.search.TypeNameRequestor; | |
import org.eclipse.jface.operation.IRunnableWithProgress; | |
import org.eclipse.jst.ws.jaxws.testutils.threading.TestContext; | |
import org.eclipse.jst.ws.jaxws.utils.logging.ILogger; | |
import org.eclipse.jst.ws.jaxws.utils.logging.Logger; | |
import org.eclipse.swt.widgets.Display; | |
import org.eclipse.ui.PlatformUI; | |
public class JobUtils | |
{ | |
@SuppressWarnings("deprecation") | |
public static void waitForJobsInterruptable() throws InterruptedException | |
{ | |
while (Platform.getJobManager().currentJob() != null) | |
{ | |
delay(5); | |
} | |
} | |
public static void waitForJobs() throws JavaModelException | |
{ | |
waitForDummyJob(Job.INTERACTIVE); | |
while (true) | |
{ | |
try | |
{ | |
waitForJobsInterruptable(); | |
break; | |
} catch (InterruptedException ie) | |
{ | |
} | |
} | |
// i036509 added couse waiting for jobs is not enought | |
waitForIndexer(); | |
// Force notifications | |
waitForNotifications(); | |
} | |
public static void delay(final long millis) throws InterruptedException | |
{ | |
Display display = Display.getCurrent(); | |
// if this is the UI thread, then process the input | |
if (display != null) | |
{ | |
final long entTimeMillis = System.currentTimeMillis() + millis; | |
while (System.currentTimeMillis() < entTimeMillis) | |
{ | |
if (!display.readAndDispatch()) | |
{ | |
display.sleep(); | |
} | |
} | |
display.update(); | |
} else | |
{ | |
Thread.sleep(1000); | |
} | |
} | |
public static void waitForIndexer() throws JavaModelException | |
{ | |
new SearchEngine().searchAllTypeNames(null,SearchPattern.R_EXACT_MATCH, null, | |
SearchPattern.R_CASE_SENSITIVE, IJavaSearchConstants.CLASS, SearchEngine | |
.createJavaSearchScope(new IJavaElement[0]), new TypeNameRequestor() | |
{ | |
@SuppressWarnings("unused") | |
public void acceptClass(char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, | |
String path) | |
{ | |
} | |
@SuppressWarnings("unused") | |
public void acceptInterface(char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, | |
String path) | |
{ | |
} | |
}, IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, null); | |
} | |
/** | |
* Schedule a dummy job with the priority specified and wait for it is done | |
*/ | |
private static void waitForDummyJob(final int priority) | |
{ | |
try | |
{ | |
waitForDummyJobWithPrio(priority); | |
} | |
catch(InterruptedException e) | |
{ | |
} | |
} | |
private static void waitForDummyJobWithPrio(final int prio) throws InterruptedException | |
{ | |
Job myDummyJob = new Job("DUMMY"){ | |
@Override | |
protected IStatus run(IProgressMonitor monitor) | |
{ | |
return Status.OK_STATUS; | |
}}; | |
myDummyJob.setPriority(prio); | |
myDummyJob.setUser(false); | |
myDummyJob.schedule(); | |
myDummyJob.join(); | |
} | |
/** | |
* Forces delivering of notification events. The implementation of the method is "inspired" by NotificationManager's notification job | |
* @throws InterruptedException | |
*/ | |
private static void waitForNotifications() | |
{ | |
final IWorkspace workspace = ResourcesPlugin.getWorkspace(); | |
final IWorkspaceRunnable dummyRunnable = new IWorkspaceRunnable(){ | |
public void run(IProgressMonitor monitor) throws CoreException | |
{ | |
} | |
}; | |
final Job notifForcingJob = new Job("Delivering notifications..."){ | |
@Override | |
protected IStatus run(IProgressMonitor monitor) | |
{ | |
try | |
{ | |
workspace.run(dummyRunnable, null, IWorkspace.AVOID_UPDATE, null); | |
} catch (CoreException e) | |
{ | |
logger().logDebug( e.getMessage(), e ); | |
} | |
return Status.OK_STATUS; | |
}}; | |
syncExecJob(notifForcingJob, PlatformUI.getWorkbench().getDisplay()); | |
} | |
public static void waitForJobsSlow() throws JavaModelException | |
{ | |
waitForJobs(); | |
waitForDummyJob(Job.DECORATE); | |
waitForEventLoop(); | |
} | |
private static void waitForEventLoop() | |
{ | |
final Display display = PlatformUI.getWorkbench().getDisplay(); | |
final Runnable runnable = new Runnable(){ | |
public void run() | |
{ | |
// Let the display process the events in its queue | |
while(display.readAndDispatch()){}; | |
}}; | |
if(Display.getCurrent() != null) | |
{ | |
runnable.run(); | |
} | |
else | |
{ | |
display.syncExec(runnable); | |
} | |
} | |
/** | |
* Executes synchronously (schedules and joins) the job specified.<br> | |
* If the method is called from the UI thread, the job is scheduled and joined in a modal context thread thus letting the event loop process asynchronous events<br> | |
* If the method is called from a worker thread, the job is scheduled and joined in the caller thread. | |
* | |
* @param job | |
* @param display | |
*/ | |
private static void syncExecJob(final Job job, final Display display) | |
{ | |
final IRunnableWithProgress runnable = new IRunnableWithProgress() | |
{ | |
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException | |
{ | |
job.schedule(); | |
try | |
{ | |
job.join(); | |
} catch (InterruptedException e) | |
{ | |
logger().logDebug(e.getMessage(), e); | |
} | |
} | |
}; | |
try | |
{ | |
TestContext.run(runnable, Display.getCurrent() != null, new NullProgressMonitor(), display); | |
} catch (InvocationTargetException e) | |
{ | |
logger().logDebug(e.getMessage(), e); | |
} catch (InterruptedException e) | |
{ | |
logger().logDebug(e.getMessage(), e); | |
} | |
} | |
private static ILogger logger() | |
{ | |
return new Logger(); | |
} | |
} |