package org.argeo.slc.core.test.tree; import java.util.Vector; import org.argeo.slc.core.structure.tree.TreeSPath; import org.argeo.slc.core.test.NumericTRId; import org.argeo.slc.core.test.TestResult; import org.argeo.slc.core.test.TestResultListener; import org.argeo.slc.core.test.TestResultPart; /** * Abstract asynchronous implementation of a listener listening to a * TreeTestResult. * * @see TreeTestResult */ public abstract class AsynchronousTreeTestResultListener implements TestResultListener, Runnable { private Vector partStructs = new Vector(); private Thread thread; /** Starts the underlying thread. */ public void init() { thread = new Thread(this); thread.start(); } /** Finish the remaining and destroy */ public void close() { synchronized (partStructs) { // TODO: put a timeout while (partStructs.size() != 0) { try { partStructs.wait(500); } catch (InterruptedException e) { // silent } } thread = null; partStructs.notifyAll(); } } public final void resultPartAdded(TestResult testResult, TestResultPart testResultPart) { TreeTestResult result = (TreeTestResult) testResult; synchronized (partStructs) { partStructs.add(new PartStruct(result.getCurrentPath(), (NumericTRId) result.getTestResultId(), testResultPart, result)); partStructs.notifyAll(); } } /** Called when a result part has been added. */ protected abstract void resultPartAdded(PartStruct partStruct); public void run() { while (thread != null) { synchronized (partStructs) { for (PartStruct partStruct : partStructs) { resultPartAdded(partStruct); } partStructs.clear(); partStructs.notifyAll(); while (partStructs.size() == 0) { try { partStructs.wait(); } catch (InterruptedException e) { // silent } } } } } /** Structure used to pass tree specific information to subclasses. */ protected static class PartStruct { /** The tree path of this part. */ public final TreeSPath path; /** The test result id of the related test result */ public final NumericTRId resultId; /** The part itself */ public final TestResultPart part; /** The tree test result itself. */ public final TreeTestResult result; /** Constructor */ public PartStruct(TreeSPath path, NumericTRId resultId, TestResultPart part, TreeTestResult result) { super(); this.path = path; this.resultId = resultId; this.part = part; this.result = result; } } }