Skip to content

Commit adb9404

Browse files
committed
Work on iluwatar#385, created project and provided two mute methods
1 parent 35d6a54 commit adb9404

File tree

6 files changed

+302
-0
lines changed

6 files changed

+302
-0
lines changed

mute-idiom/pom.xml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
4+
The MIT License
5+
Copyright (c) 2014 Ilkka Seppälä
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in
15+
all copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
THE SOFTWARE.
24+
25+
-->
26+
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
27+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
28+
<modelVersion>4.0.0</modelVersion>
29+
<parent>
30+
<groupId>com.iluwatar</groupId>
31+
<artifactId>java-design-patterns</artifactId>
32+
<version>1.11.0-SNAPSHOT</version>
33+
</parent>
34+
<artifactId>mute-idiom</artifactId>
35+
<dependencies>
36+
<dependency>
37+
<groupId>junit</groupId>
38+
<artifactId>junit</artifactId>
39+
<scope>test</scope>
40+
</dependency>
41+
<dependency>
42+
<groupId>org.mockito</groupId>
43+
<artifactId>mockito-core</artifactId>
44+
<scope>test</scope>
45+
</dependency>
46+
</dependencies>
47+
</project>
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
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.mute;
24+
25+
import java.io.ByteArrayOutputStream;
26+
import java.sql.Connection;
27+
import java.sql.SQLException;
28+
29+
public class App {
30+
31+
public static void main(String[] args) {
32+
33+
useOfLoggedMute();
34+
35+
useOfMute();
36+
}
37+
38+
/*
39+
* Typically used when the API declares some exception but cannot do so. Usually a signature mistake.
40+
* In this example out is not supposed to throw exception as it is a ByteArrayOutputStream. So we
41+
* utilize mute, which will throw AssertionError if unexpected exception occurs.
42+
*/
43+
private static void useOfMute() {
44+
ByteArrayOutputStream out = new ByteArrayOutputStream();
45+
Mute.mute(() -> out.write("Hello".getBytes()));
46+
}
47+
48+
private static void useOfLoggedMute() {
49+
Connection connection = openConnection();
50+
try {
51+
readStuff(connection);
52+
} catch (SQLException ex) {
53+
ex.printStackTrace();
54+
} finally {
55+
closeConnection(connection);
56+
}
57+
}
58+
59+
/*
60+
* All we can do while failed close of connection is to log it.
61+
*/
62+
private static void closeConnection(Connection connection) {
63+
if (connection != null) {
64+
Mute.loggedMute(() -> connection.close());
65+
}
66+
}
67+
68+
private static void readStuff(Connection connection) throws SQLException {
69+
if (connection != null) {
70+
connection.createStatement();
71+
}
72+
}
73+
74+
private static Connection openConnection() {
75+
return null;
76+
}
77+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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.mute;
24+
25+
/**
26+
* A runnable which may throw exception on execution.
27+
*
28+
*/
29+
@FunctionalInterface
30+
public interface CheckedRunnable {
31+
/**
32+
* Same as {@link Runnable#run()} with a possibility of exception in execution.
33+
* @throws Exception if any exception occurs.
34+
*/
35+
public void run() throws Exception;
36+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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.mute;
24+
25+
import java.io.ByteArrayOutputStream;
26+
import java.io.IOException;
27+
28+
/**
29+
* A utility class that allows you to utilize mute idiom.
30+
*/
31+
public final class Mute {
32+
33+
/**
34+
* Executes the <code>runnable</code> and throws the exception occurred within a {@link AssertionError}.
35+
* This method should be utilized to mute the operations that are guaranteed not to throw an exception.
36+
* For instance {@link ByteArrayOutputStream#write(byte[])} declares in it's signature that it can throw
37+
* an {@link IOException}, but in reality it cannot. This is because the bulk write method is not overridden
38+
* in {@link ByteArrayOutputStream}.
39+
*
40+
* @param runnable a runnable that should never throw an exception on execution.
41+
*/
42+
public static void mute(CheckedRunnable runnable) {
43+
try {
44+
runnable.run();
45+
} catch (Exception e) {
46+
throw new AssertionError(e);
47+
}
48+
}
49+
50+
/**
51+
* Executes the <code>runnable</code> and logs the exception occurred on {@link System#err}.
52+
* This method should be utilized to mute the operations about which most you can do is log.
53+
* For instance while closing a connection to database, all you can do is log the exception
54+
* occurred.
55+
*
56+
* @param runnable a runnable that may throw an exception on execution.
57+
*/
58+
public static void loggedMute(CheckedRunnable runnable) {
59+
try {
60+
runnable.run();
61+
} catch (Exception e) {
62+
e.printStackTrace();
63+
}
64+
}
65+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.iluwatar.mute;
2+
3+
import org.junit.Test;
4+
5+
/**
6+
* Tests that Mute idiom example runs without errors.
7+
*
8+
*/
9+
public class AppTest {
10+
11+
@Test
12+
public void test() {
13+
App.main(null);
14+
}
15+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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.mute;
24+
25+
import static org.junit.Assert.assertTrue;
26+
27+
import java.io.ByteArrayOutputStream;
28+
import java.io.IOException;
29+
import java.io.PrintStream;
30+
31+
import org.junit.Rule;
32+
import org.junit.Test;
33+
import org.junit.rules.ExpectedException;
34+
35+
public class MuteTest {
36+
37+
private static final String MESSAGE = "should not occur";
38+
39+
@Rule public ExpectedException exception = ExpectedException.none();
40+
41+
@Test
42+
public void muteShouldRethrowUnexpectedExceptionAsAssertionError() throws Exception {
43+
exception.expect(AssertionError.class);
44+
exception.expectMessage(MESSAGE);
45+
46+
Mute.mute(() -> methodThrowingException());
47+
}
48+
49+
private void methodThrowingException() throws Exception {
50+
throw new Exception(MESSAGE);
51+
}
52+
53+
@Test
54+
public void loggedMuteShouldLogExceptionTraceBeforeSwallowingIt() throws IOException {
55+
ByteArrayOutputStream stream = new ByteArrayOutputStream();
56+
System.setErr(new PrintStream(stream));
57+
58+
Mute.loggedMute(() -> methodThrowingException());
59+
60+
assertTrue(new String(stream.toByteArray()).contains(MESSAGE));
61+
}
62+
}

0 commit comments

Comments
 (0)