summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKjetil Ørbekk <kjetil.orbekk@gmail.com>2012-02-27 15:42:42 +0100
committerKjetil Ørbekk <kjetil.orbekk@gmail.com>2012-02-27 15:42:42 +0100
commit500f94ce6780e96e503d6e5d9d46b5d537813717 (patch)
tree5d71d53c4356c40d5563cddcb5be48fd38e7ee6b
parenta8560de9c330285db0d7cf31398daad1090038b4 (diff)
Add DelayedOperation<T> class.
A DelayedOperation represents an asynchronious operation.
-rw-r--r--same/src/main/java/com/orbekk/util/DelayedOperation.java99
-rw-r--r--same/src/test/java/com/orbekk/util/DelayedOperationTest.java35
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());
+ }
+}