Skip to content

Commit 95cf9fe

Browse files
committed
Work on iluwatar#403, made example readable and moved methods into utility
1 parent 7697063 commit 95cf9fe

File tree

4 files changed

+172
-76
lines changed

4 files changed

+172
-76
lines changed

promise/etc/promise.png

-3.73 KB
Loading

promise/etc/promise.ucls

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
<position height="-1" width="-1" x="524" y="313"/>
2626
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
2727
sort-features="false" accessors="true" visibility="true">
28-
<attributes public="true" package="false" protected="true" private="true" static="true"/>
28+
<attributes public="true" package="false" protected="true" private="false" static="true"/>
2929
<operations public="true" package="false" protected="true" private="true" static="true"/>
3030
</display>
3131
</class>
@@ -67,42 +67,38 @@
6767
</interface>
6868
<class id="8" language="java" name="com.iluwatar.promise.App" project="promise"
6969
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"/>
70+
<position height="-1" width="-1" x="822" y="251"/>
7171
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
7272
sort-features="false" accessors="true" visibility="true">
73-
<attributes public="true" package="true" protected="true" private="true" static="true"/>
73+
<attributes public="true" package="true" protected="true" private="false" static="true"/>
7474
<operations public="true" package="true" protected="true" private="false" static="true"/>
7575
</display>
7676
</class>
77-
<generalization id="9">
78-
<end type="SOURCE" refId="1"/>
79-
<end type="TARGET" refId="3"/>
80-
</generalization>
81-
<realization id="10">
77+
<realization id="9">
8278
<end type="SOURCE" refId="3"/>
8379
<end type="TARGET" refId="2"/>
8480
</realization>
85-
<dependency id="11">
81+
<dependency id="10">
8682
<end type="SOURCE" refId="1"/>
8783
<end type="TARGET" refId="6"/>
8884
</dependency>
85+
<dependency id="11">
86+
<end type="SOURCE" refId="1"/>
87+
<end type="TARGET" refId="5"/>
88+
</dependency>
8989
<dependency id="12">
9090
<end type="SOURCE" refId="8"/>
9191
<end type="TARGET" refId="1"/>
9292
</dependency>
9393
<dependency id="13">
94-
<end type="SOURCE" refId="8"/>
95-
<end type="TARGET" refId="4"/>
96-
</dependency>
97-
<dependency id="14">
9894
<end type="SOURCE" refId="1"/>
9995
<end type="TARGET" refId="7"/>
10096
</dependency>
101-
<dependency id="15">
97+
<generalization id="14">
10298
<end type="SOURCE" refId="1"/>
103-
<end type="TARGET" refId="5"/>
104-
</dependency>
105-
<dependency id="16">
99+
<end type="TARGET" refId="3"/>
100+
</generalization>
101+
<dependency id="15">
106102
<end type="SOURCE" refId="1"/>
107103
<end type="TARGET" refId="4"/>
108104
</dependency>

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

Lines changed: 68 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,10 @@
2121
* THE SOFTWARE.
2222
*/
2323
package com.iluwatar.promise;
24-
25-
import java.io.BufferedReader;
26-
import java.io.File;
27-
import java.io.FileReader;
28-
import java.io.FileWriter;
29-
import java.io.IOException;
30-
import java.io.InputStreamReader;
31-
import java.io.Reader;
32-
import java.net.URL;
3324
import java.util.Map;
3425
import java.util.concurrent.CompletableFuture;
26+
import java.util.concurrent.CountDownLatch;
3527
import java.util.concurrent.ExecutionException;
36-
import java.util.concurrent.Executor;
3728
import java.util.concurrent.ExecutorService;
3829
import java.util.concurrent.Executors;
3930

@@ -59,7 +50,12 @@
5950
*/
6051
public class App {
6152

53+
private static final String URL = "https://raw.githubusercontent.com/iluwatar/java-design-patterns/Promise/promise/README.md";
54+
private ExecutorService executor;
55+
private CountDownLatch canStop = new CountDownLatch(2);
56+
6257
private App() {
58+
executor = Executors.newFixedThreadPool(2);
6359
}
6460

6561
/**
@@ -69,67 +65,80 @@ private App() {
6965
* @throws ExecutionException if an execution error occurs.
7066
*/
7167
public static void main(String[] args) throws InterruptedException, ExecutionException {
72-
ExecutorService executor = Executors.newSingleThreadExecutor();
68+
App app = new App();
7369
try {
74-
promiseUsage(executor);
70+
app.run();
7571
} finally {
76-
executor.shutdownNow();
72+
app.stop();
7773
}
7874
}
7975

80-
private static void promiseUsage(Executor executor)
81-
throws InterruptedException, ExecutionException {
82-
String urlString = "https://raw.githubusercontent.com/iluwatar/java-design-patterns/Promise/promise/README.md";
83-
Promise<Integer> lineCountPromise = new Promise<String>().fulfillInAsync(() -> {
84-
return downloadFile(urlString);
85-
}, executor).then(fileLocation -> {
86-
return countLines(fileLocation);
87-
});
76+
private void run() throws InterruptedException, ExecutionException {
77+
promiseUsage();
78+
}
79+
80+
private void promiseUsage() {
8881

89-
Promise<Map<Character, Integer>> charFrequencyPromise = new Promise<String>().fulfillInAsync(() -> {
90-
return String.valueOf(downloadFile(urlString));
91-
}, executor).then(fileLocation -> {
92-
return characterFrequency(fileLocation);
93-
});
82+
countLines()
83+
.then(
84+
count -> {
85+
System.out.println("Line count is: " + count);
86+
taskCompleted();
87+
}
88+
);
9489

95-
lineCountPromise.get();
96-
System.out.println("Line count is: " + lineCountPromise.get());
97-
charFrequencyPromise.get();
98-
System.out.println("Char frequency is: " + charFrequencyPromise.get());
90+
lowestCharFrequency()
91+
.then(
92+
charFrequency -> {
93+
System.out.println("Char with lowest frequency is: " + charFrequency);
94+
taskCompleted();
95+
}
96+
);
9997
}
10098

101-
private static Map<Character, Integer> characterFrequency(String fileLocation) {
102-
// TODO Auto-generated method stub
103-
return null;
99+
private Promise<Character> lowestCharFrequency() {
100+
return characterFrequency()
101+
.then(
102+
charFrequency -> {
103+
return Utility.lowestFrequencyChar(charFrequency).orElse(null);
104+
}
105+
);
104106
}
105107

106-
private static Integer countLines(String fileLocation) {
107-
int lineCount = 0;
108-
try (Reader reader = new FileReader(fileLocation);
109-
BufferedReader bufferedReader = new BufferedReader(reader);) {
110-
for (String line; (line = bufferedReader.readLine()) != null; ) {
111-
lineCount++;
112-
}
113-
} catch (IOException ex) {
114-
ex.printStackTrace();
115-
}
116-
return lineCount;
108+
private Promise<Map<Character, Integer>> characterFrequency() {
109+
return download(URL)
110+
.then(
111+
fileLocation -> {
112+
return Utility.characterFrequency(fileLocation);
113+
}
114+
);
117115
}
118116

119-
private static String downloadFile(String urlString) throws InterruptedException, IOException {
120-
URL url = new URL(urlString);
121-
File file = File.createTempFile("promise_pattern", null);
122-
try (Reader reader = new InputStreamReader(url.openStream());
123-
BufferedReader bufferedReader = new BufferedReader(reader);
124-
FileWriter writer = new FileWriter(file)) {
125-
for (String line; (line = bufferedReader.readLine()) != null; ) {
126-
writer.write(line);
127-
writer.write("\n");
128-
}
129-
} catch (IOException ex) {
130-
ex.printStackTrace();
131-
}
132-
System.out.println("File downloaded at: " + file.getAbsolutePath());
133-
return file.getAbsolutePath();
117+
private Promise<Integer> countLines() {
118+
return download(URL)
119+
.then(
120+
fileLocation -> {
121+
return Utility.countLines(fileLocation);
122+
}
123+
);
124+
}
125+
126+
private Promise<String> download(String urlString) {
127+
Promise<String> downloadPromise = new Promise<String>()
128+
.fulfillInAsync(
129+
() -> {
130+
return Utility.downloadFile(urlString);
131+
}, executor);
132+
133+
return downloadPromise;
134+
}
135+
136+
private void stop() throws InterruptedException {
137+
canStop.await();
138+
executor.shutdownNow();
139+
}
140+
141+
private void taskCompleted() {
142+
canStop.countDown();
134143
}
135144
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package com.iluwatar.promise;
2+
3+
import java.io.BufferedReader;
4+
import java.io.File;
5+
import java.io.FileReader;
6+
import java.io.FileWriter;
7+
import java.io.IOException;
8+
import java.io.InputStreamReader;
9+
import java.io.Reader;
10+
import java.net.MalformedURLException;
11+
import java.net.URL;
12+
import java.util.HashMap;
13+
import java.util.Iterator;
14+
import java.util.Map;
15+
import java.util.Optional;
16+
import java.util.Map.Entry;
17+
18+
public class Utility {
19+
20+
public static Map<Character, Integer> characterFrequency(String fileLocation) {
21+
Map<Character, Integer> characterToFrequency = new HashMap<>();
22+
try (Reader reader = new FileReader(fileLocation);
23+
BufferedReader bufferedReader = new BufferedReader(reader);) {
24+
for (String line; (line = bufferedReader.readLine()) != null;) {
25+
for (char c : line.toCharArray()) {
26+
if (!characterToFrequency.containsKey(c)) {
27+
characterToFrequency.put(c, 1);
28+
} else {
29+
characterToFrequency.put(c, characterToFrequency.get(c) + 1);
30+
}
31+
}
32+
}
33+
} catch (IOException ex) {
34+
ex.printStackTrace();
35+
}
36+
return characterToFrequency;
37+
}
38+
39+
public static Optional<Character> lowestFrequencyChar(Map<Character, Integer> charFrequency) {
40+
Optional<Character> lowestFrequencyChar = Optional.empty();
41+
if (charFrequency.isEmpty()) {
42+
return lowestFrequencyChar;
43+
}
44+
45+
Iterator<Entry<Character, Integer>> iterator = charFrequency.entrySet().iterator();
46+
Entry<Character, Integer> entry = iterator.next();
47+
int minFrequency = entry.getValue();
48+
lowestFrequencyChar = Optional.of(entry.getKey());
49+
50+
while (iterator.hasNext()) {
51+
entry = iterator.next();
52+
if (entry.getValue() < minFrequency) {
53+
minFrequency = entry.getValue();
54+
lowestFrequencyChar = Optional.of(entry.getKey());
55+
}
56+
}
57+
58+
return lowestFrequencyChar;
59+
}
60+
61+
public static Integer countLines(String fileLocation) {
62+
int lineCount = 0;
63+
try (Reader reader = new FileReader(fileLocation);
64+
BufferedReader bufferedReader = new BufferedReader(reader);) {
65+
while (bufferedReader.readLine() != null) {
66+
lineCount++;
67+
}
68+
} catch (IOException ex) {
69+
ex.printStackTrace();
70+
}
71+
return lineCount;
72+
}
73+
74+
public static String downloadFile(String urlString) throws MalformedURLException, IOException {
75+
System.out.println("Downloading contents from url: " + urlString);
76+
URL url = new URL(urlString);
77+
File file = File.createTempFile("promise_pattern", null);
78+
try (Reader reader = new InputStreamReader(url.openStream());
79+
BufferedReader bufferedReader = new BufferedReader(reader);
80+
FileWriter writer = new FileWriter(file)) {
81+
for (String line; (line = bufferedReader.readLine()) != null; ) {
82+
writer.write(line);
83+
writer.write("\n");
84+
}
85+
System.out.println("File downloaded at: " + file.getAbsolutePath());
86+
return file.getAbsolutePath();
87+
} catch (IOException ex) {
88+
throw ex;
89+
}
90+
}
91+
}

0 commit comments

Comments
 (0)