Skip to content

Commit 09ba5ca

Browse files
committed
Work on iluwatar#403, added class diagrams and javadocs
1 parent eb560f5 commit 09ba5ca

7 files changed

Lines changed: 344 additions & 3 deletions

File tree

promise/etc/promise.png

58.1 KB
Loading

promise/etc/promise.ucls

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<class-diagram version="1.1.10" icons="true" automaticImage="PNG" always-add-relationships="false"
3+
generalizations="true" realizations="true" associations="true" dependencies="false" nesting-relationships="true"
4+
router="FAN">
5+
<class id="1" language="java" name="com.iluwatar.promise.Promise" project="promise"
6+
file="/promise/src/main/java/com/iluwatar/promise/Promise.java" binary="false" corner="BOTTOM_RIGHT">
7+
<position height="-1" width="-1" x="524" y="541"/>
8+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
9+
sort-features="false" accessors="true" visibility="true">
10+
<attributes public="true" package="true" protected="true" private="false" static="true"/>
11+
<operations public="true" package="false" protected="true" private="false" static="true"/>
12+
</display>
13+
</class>
14+
<interface id="2" language="java" name="java.util.concurrent.Future" project="async-method-invocation"
15+
file="/usr/lib/java/jdk1.8.0_45/jre/lib/rt.jar" binary="true" corner="BOTTOM_RIGHT">
16+
<position height="-1" width="-1" x="527" y="94"/>
17+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
18+
sort-features="false" accessors="true" visibility="true">
19+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
20+
<operations public="true" package="true" protected="true" private="true" static="true"/>
21+
</display>
22+
</interface>
23+
<class id="3" language="java" name="com.iluwatar.promise.PromiseSupport" project="promise"
24+
file="/promise/src/main/java/com/iluwatar/promise/PromiseSupport.java" binary="false" corner="BOTTOM_RIGHT">
25+
<position height="-1" width="-1" x="524" y="313"/>
26+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
27+
sort-features="false" accessors="true" visibility="true">
28+
<attributes public="true" package="false" protected="true" private="true" static="true"/>
29+
<operations public="true" package="false" protected="true" private="true" static="true"/>
30+
</display>
31+
</class>
32+
<interface id="4" language="java" name="java.util.concurrent.Executor" project="async-method-invocation"
33+
file="/usr/lib/java/jdk1.8.0_45/jre/lib/rt.jar" binary="true" corner="BOTTOM_RIGHT">
34+
<position height="-1" width="-1" x="834" y="573"/>
35+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
36+
sort-features="false" accessors="true" visibility="true">
37+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
38+
<operations public="true" package="true" protected="true" private="true" static="true"/>
39+
</display>
40+
</interface>
41+
<interface id="5" language="java" name="java.util.concurrent.Callable" project="async-method-invocation"
42+
file="/usr/lib/java/jdk1.8.0_45/jre/lib/rt.jar" binary="true" corner="BOTTOM_RIGHT">
43+
<position height="-1" width="-1" x="825" y="433"/>
44+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
45+
sort-features="false" accessors="true" visibility="true">
46+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
47+
<operations public="true" package="true" protected="true" private="true" static="true"/>
48+
</display>
49+
</interface>
50+
<interface id="6" language="java" name="java.util.function.Consumer" project="async-method-invocation"
51+
file="/usr/lib/java/jdk1.8.0_45/jre/lib/rt.jar" binary="true" corner="BOTTOM_RIGHT">
52+
<position height="-1" width="-1" x="162" y="437"/>
53+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
54+
sort-features="false" accessors="true" visibility="true">
55+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
56+
<operations public="true" package="true" protected="true" private="false" static="true"/>
57+
</display>
58+
</interface>
59+
<interface id="7" language="java" name="java.util.function.Function" project="async-method-invocation"
60+
file="/usr/lib/java/jdk1.8.0_45/jre/lib/rt.jar" binary="true" corner="BOTTOM_RIGHT">
61+
<position height="-1" width="-1" x="168" y="591"/>
62+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
63+
sort-features="false" accessors="true" visibility="true">
64+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
65+
<operations public="true" package="true" protected="true" private="false" static="false"/>
66+
</display>
67+
</interface>
68+
<class id="8" language="java" name="com.iluwatar.promise.App" project="promise"
69+
file="/promise/src/main/java/com/iluwatar/promise/App.java" binary="false" corner="BOTTOM_RIGHT">
70+
<position height="-1" width="-1" x="992" y="206"/>
71+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
72+
sort-features="false" accessors="true" visibility="true">
73+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
74+
<operations public="true" package="true" protected="true" private="false" static="true"/>
75+
</display>
76+
</class>
77+
<realization id="9">
78+
<end type="SOURCE" refId="3"/>
79+
<end type="TARGET" refId="2"/>
80+
</realization>
81+
<dependency id="10">
82+
<end type="SOURCE" refId="8"/>
83+
<end type="TARGET" refId="1"/>
84+
</dependency>
85+
<generalization id="11">
86+
<end type="SOURCE" refId="1"/>
87+
<end type="TARGET" refId="3"/>
88+
</generalization>
89+
<dependency id="12">
90+
<end type="SOURCE" refId="1"/>
91+
<end type="TARGET" refId="4"/>
92+
</dependency>
93+
<dependency id="13">
94+
<end type="SOURCE" refId="1"/>
95+
<end type="TARGET" refId="7"/>
96+
</dependency>
97+
<dependency id="14">
98+
<end type="SOURCE" refId="8"/>
99+
<end type="TARGET" refId="4"/>
100+
</dependency>
101+
<dependency id="15">
102+
<end type="SOURCE" refId="1"/>
103+
<end type="TARGET" refId="6"/>
104+
</dependency>
105+
<dependency id="16">
106+
<end type="SOURCE" refId="1"/>
107+
<end type="TARGET" refId="5"/>
108+
</dependency>
109+
<classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
110+
sort-features="false" accessors="true" visibility="true">
111+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
112+
<operations public="true" package="true" protected="true" private="true" static="true"/>
113+
</classifier-display>
114+
<association-display labels="true" multiplicity="true"/>
115+
</class-diagram>

promise/src/main/java/com/iluwatar/promise/App.java

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,60 @@
1+
/**
2+
* The MIT License
3+
* Copyright (c) 2014 Ilkka Seppälä
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
123
package com.iluwatar.promise;
224

25+
import java.util.concurrent.CompletableFuture;
326
import java.util.concurrent.ExecutionException;
427
import java.util.concurrent.Executor;
528
import java.util.concurrent.ExecutorService;
629
import java.util.concurrent.Executors;
730

831
/**
932
*
10-
* Application that uses promise pattern.
33+
* <p>The Promise object is used for asynchronous computations. A Promise represents an operation that
34+
* hasn't completed yet, but is expected in the future.
35+
*
36+
* <p>A Promise represents a proxy for a value not necessarily known when the promise is created. It
37+
* allows you to associate dependent promises to an asynchronous action's eventual success value or
38+
* failure reason. This lets asynchronous methods return values like synchronous methods: instead of the final
39+
* value, the asynchronous method returns a promise of having a value at some point in the future.
40+
*
41+
* <p>Promises provide a few advantages over callback objects:
42+
* <ul>
43+
* <li> Functional composition and error handling
44+
* <li> Prevents callback hell and provides callback aggregation
45+
* </ul>
46+
*
47+
* @see CompletableFuture
1148
*/
1249
public class App {
1350

51+
private App() {
52+
}
53+
1454
/**
1555
* Program entry point
1656
* @param args arguments
17-
* @throws InterruptedException if main thread is interruped.
57+
* @throws InterruptedException if main thread is interrupted.
1858
* @throws ExecutionException if an execution error occurs.
1959
*/
2060
public static void main(String[] args) throws InterruptedException, ExecutionException {

promise/src/main/java/com/iluwatar/promise/Promise.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
/**
2+
* The MIT License
3+
* Copyright (c) 2014 Ilkka Seppälä
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
123
package com.iluwatar.promise;
224

325
import java.util.concurrent.Callable;
@@ -8,6 +30,7 @@
830

931
/**
1032
* Implements the promise pattern.
33+
*
1134
* @param <T> type of result.
1235
*/
1336
public class Promise<T> extends PromiseSupport<T> {
@@ -41,7 +64,7 @@ public void fulfillExceptionally(Exception exception) {
4164
postFulfillment();
4265
}
4366

44-
void postFulfillment() {
67+
private void postFulfillment() {
4568
if (fulfillmentAction == null) {
4669
return;
4770
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/**
2+
* The MIT License
3+
* Copyright (c) 2014 Ilkka Seppälä
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
23+
package com.iluwatar.promise;
24+
25+
import java.util.concurrent.ExecutionException;
26+
import java.util.concurrent.Future;
27+
import java.util.concurrent.TimeUnit;
28+
import java.util.concurrent.TimeoutException;
29+
30+
/**
31+
* A really simplified implementation of future that allows completing it successfully with a value
32+
* or exceptionally with an exception.
33+
*/
34+
class PromiseSupport<T> implements Future<T> {
35+
36+
static final int RUNNING = 1;
37+
static final int FAILED = 2;
38+
static final int COMPLETED = 3;
39+
40+
final Object lock;
41+
42+
volatile int state = RUNNING;
43+
T value;
44+
Exception exception;
45+
46+
PromiseSupport() {
47+
this.lock = new Object();
48+
}
49+
50+
void fulfill(T value) {
51+
this.value = value;
52+
this.state = COMPLETED;
53+
synchronized (lock) {
54+
lock.notifyAll();
55+
}
56+
}
57+
58+
void fulfillExceptionally(Exception exception) {
59+
this.exception = exception;
60+
this.state = FAILED;
61+
synchronized (lock) {
62+
lock.notifyAll();
63+
}
64+
}
65+
66+
@Override
67+
public boolean cancel(boolean mayInterruptIfRunning) {
68+
return false;
69+
}
70+
71+
@Override
72+
public boolean isCancelled() {
73+
return false;
74+
}
75+
76+
@Override
77+
public boolean isDone() {
78+
return state > RUNNING;
79+
}
80+
81+
@Override
82+
public T get() throws InterruptedException, ExecutionException {
83+
if (state == COMPLETED) {
84+
return value;
85+
} else if (state == FAILED) {
86+
throw new ExecutionException(exception);
87+
} else {
88+
synchronized (lock) {
89+
lock.wait();
90+
if (state == COMPLETED) {
91+
return value;
92+
} else {
93+
throw new ExecutionException(exception);
94+
}
95+
}
96+
}
97+
}
98+
99+
@Override
100+
public T get(long timeout, TimeUnit unit)
101+
throws InterruptedException, ExecutionException, TimeoutException {
102+
if (state == COMPLETED) {
103+
return value;
104+
} else if (state == FAILED) {
105+
throw new ExecutionException(exception);
106+
} else {
107+
synchronized (lock) {
108+
lock.wait(unit.toMillis(timeout));
109+
if (state == COMPLETED) {
110+
return value;
111+
} else if (state == FAILED) {
112+
throw new ExecutionException(exception);
113+
} else {
114+
throw new TimeoutException();
115+
}
116+
}
117+
}
118+
}
119+
}

promise/src/test/java/com/iluwatar/promise/AppTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
/**
2+
* The MIT License
3+
* Copyright (c) 2014 Ilkka Seppälä
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
123
package com.iluwatar.promise;
224

325
import java.util.concurrent.ExecutionException;

promise/src/test/java/com/iluwatar/promise/PromiseTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
/**
2+
* The MIT License
3+
* Copyright (c) 2014 Ilkka Seppälä
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
123
package com.iluwatar.promise;
224

325
import static org.junit.Assert.assertEquals;

0 commit comments

Comments
 (0)