diff options
Diffstat (limited to 'same')
| -rw-r--r-- | same/src/main/java/com/orbekk/util/DelayedOperation.java | 99 | ||||
| -rw-r--r-- | same/src/test/java/com/orbekk/util/DelayedOperationTest.java | 35 | 
2 files changed, 134 insertions, 0 deletions
diff --git a/same/src/main/java/com/orbekk/util/DelayedOperation.java b/same/src/main/java/com/orbekk/util/DelayedOperation.java new file mode 100644 index 0000000..2c37d02 --- /dev/null +++ b/same/src/main/java/com/orbekk/util/DelayedOperation.java @@ -0,0 +1,99 @@ +package com.orbekk.util; + +public class DelayedOperation<T> { +	public static class Status { +		public final static int OK = 1; +		public final static int CONFLICT = 2; +		public final static int ERROR = 3; + +		private int status; +		private String message; +		 +		public static Status createOk() { +			return new Status(OK, ""); +		} +		 +		public static Status createConflict(String message) { +			return new Status(CONFLICT, message); +		} +		 +		public static Status createError(String message) { +			return new Status(ERROR, message); +		} +		 +		public Status(int status, String message) { +			this.status = status; +			this.message = message; +		} +		 +		@Override public String toString() { +			switch(status) { +			case OK: +				return "OK"; +			case CONFLICT: +				return "Conflicting update: " + message; +			case ERROR: +				return "Error: " + message; +			} +			throw new AssertionError("Unhandled case."); +		} +		 +		@Override public boolean equals(Object other) { +			if (!(other instanceof Status)) { +				return false; +			} +			Status o = (Status)other; +			if (o.status != this.status) { +				return false; +			} +			if (message == null) { +				return o.message == null; +			} +			return message.equals(o.message); +		} +	} +	 +	private T argument; +	private Status status; +	private boolean isDone; +	private int identifier; +	 +	public DelayedOperation(T argument) { +		this.argument = argument; +	} +	 +	public Status getStatus() { +		waitFor(); +		return status; +	} + +	public synchronized void waitFor() { +		while (!isDone) { +			try { +				wait(); +			} catch (InterruptedException e) { +				complete(new Status(Status.ERROR, "Thread interrupted.")); +			} +		} +	} +	 +	public synchronized boolean isDone() { +		return isDone; +	} +	 +	public synchronized void complete(Status status) { +		if (!isDone) { +			isDone = true; +			this.status = status; +			notifyAll(); +		} +	} +	 +	public synchronized int getIdentifier() { +		return identifier; +	} +	 +	public synchronized void setIdentifier(int identifier) { +		this.identifier = identifier; +	} +} diff --git a/same/src/test/java/com/orbekk/util/DelayedOperationTest.java b/same/src/test/java/com/orbekk/util/DelayedOperationTest.java new file mode 100644 index 0000000..b15830f --- /dev/null +++ b/same/src/test/java/com/orbekk/util/DelayedOperationTest.java @@ -0,0 +1,35 @@ +package com.orbekk.util; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class DelayedOperationTest { +	@Test public void initialOperationStatus() { +		DelayedOperation<String> operation = new DelayedOperation<String>("NotFinished"); +		assertFalse(operation.isDone()); +	} +	 +	@Test public void completedOperationReturns() { +		DelayedOperation<String> operation = new DelayedOperation<String>("Test"); +		operation.complete(DelayedOperation.Status.createOk()); +		assertTrue(operation.isDone()); +		assertEquals(DelayedOperation.Status.createOk(), operation.getStatus()); +	} + +	@Test public void concurrentTest() throws Exception { +		final DelayedOperation<String> operation = +				new DelayedOperation<String>("ConcurrentTest"); +		 +		Thread t = new Thread(new Runnable() { +			@Override +			public void run() { +				operation.waitFor(); +			} +		}); +		t.start(); +		operation.complete(DelayedOperation.Status.createError("Fail.")); +		t.join(); +		assertTrue(operation.isDone()); +	} +}  | 
