// This software is released into the Public Domain. See copying.txt for details.
package org.openstreetmap.osmosis.testutil.v0_6;
import org.openstreetmap.osmosis.core.task.v0_6.MultiSinkRunnableChangeSource;
import org.openstreetmap.osmosis.core.task.v0_6.MultiSinkRunnableSource;
import org.openstreetmap.osmosis.core.task.v0_6.RunnableSource;
/**
* Utility methods for running complicated tasks like MultiSinks.
*
* @author Igor Podolskiy
*/
public final class RunTaskUtilities {
private RunTaskUtilities() {
}
/**
* Helper method to execute a two-sink entity source.
*
* @param multiSink the multi-sink source to run.
* @param source1 the first source to feed to the sink.
* @param source2 the second source to feed to the sink.
* @return the sink entity inspector containing the result.
* @throws Exception if something goes wrong.
*/
public static SinkEntityInspector run(MultiSinkRunnableSource multiSink,
RunnableSource source1, RunnableSource source2) throws Exception {
return run(multiSink, source1, source2, null);
}
/**
* Helper method to execute a two-sink entity source.
*
* @param multiSink the multi-sink source to run.
* @param source1 the first source to feed to the sink.
* @param source2 the second source to feed to the sink.
* @param exceptionHandler the exception handler to attach to threads.
* @return the sink entity inspector containing the result.
* @throws Exception if something goes wrong.
*/
public static SinkEntityInspector run(MultiSinkRunnableSource multiSink,
RunnableSource source1, RunnableSource source2,
Thread.UncaughtExceptionHandler exceptionHandler) throws Exception {
SinkEntityInspector inspector = new SinkEntityInspector();
source1.setSink(multiSink.getSink(0));
source2.setSink(multiSink.getSink(1));
multiSink.setSink(inspector);
runCore(multiSink, source1, source2, exceptionHandler);
return inspector;
}
/**
* Helper method to execute a two-sink change source.
*
* @param multiSink the twp-sink change source to run.
* @param source1 the first source to feed to the sink.
* @param source2 the second source to feed to the sink.
* @return the sink change inspector containing the result.
* @throws Exception if something goes wrong.
*/
public static SinkChangeInspector run(MultiSinkRunnableChangeSource multiSink,
RunnableSource source1, RunnableSource source2) throws Exception {
return run(multiSink, source1, source2, null);
}
/**
* Helper method to execute a two-sink change source.
*
* @param multiSink the twp-sink change source to run.
* @param source1 the first source to feed to the sink.
* @param source2 the second source to feed to the sink.
* @param exceptionHandler the exception handler to attach to threads.
* @return the sink change inspector containing the result.
* @throws Exception if something goes wrong.
*/
public static SinkChangeInspector run(MultiSinkRunnableChangeSource multiSink,
RunnableSource source1, RunnableSource source2,
Thread.UncaughtExceptionHandler exceptionHandler) throws Exception {
SinkChangeInspector inspector = new SinkChangeInspector();
source1.setSink(multiSink.getSink(0));
source2.setSink(multiSink.getSink(1));
multiSink.setChangeSink(inspector);
runCore(multiSink, source1, source2, exceptionHandler);
return inspector;
}
private static void runCore(Runnable multiSink,
Runnable source1, Runnable source2,
Thread.UncaughtExceptionHandler exceptionHandler)
throws InterruptedException {
Thread sourceThread1 = new Thread(source1);
Thread sourceThread2 = new Thread(source2);
Thread sinkThread = new Thread(multiSink);
if (exceptionHandler != null) {
sourceThread1.setUncaughtExceptionHandler(exceptionHandler);
sourceThread2.setUncaughtExceptionHandler(exceptionHandler);
sinkThread.setUncaughtExceptionHandler(exceptionHandler);
}
sinkThread.start();
sourceThread1.start();
sourceThread2.start();
sinkThread.join();
sourceThread1.join();
sourceThread2.join();
}
}