/
Res.java
86 lines (76 loc) · 2.06 KB
/
Res.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package uk.kludje;
/**
* Adapts any type to {@link AutoCloseable} so that its instances can be closed by try blocks.
*
* Usage:
*
* <pre><code>
* try (Res<SomeResource> someResource = Res.res(SomeResource::release, new SomeResource)) {
* someResource.unwrap().foo();
* }
* </code></pre>
*
* @param <R> the underlying resource type
*/
public class Res<R> implements CloseableResource {
private final CloseFunction<R> closeFunction;
private final R resource;
private Res(CloseFunction<R> closeFunction, R resource) {
Fatal.when(closeFunction == null, "closeFunction == null");
Fatal.when(resource == null, "resource == null");
this.closeFunction = closeFunction;
this.resource = resource;
}
/**
* @return the resource instance
*/
public R unwrap() {
return resource;
}
/**
* Throws any exception thrown by {@link CloseFunction#close(Object)}
* including checked exceptions.
*
* If the {@link CloseFunction} throws a checked exception not declared by any other call use {@link #expected()}
* to tell the compiler to expect it.
*/
@Override
public void close() {
try {
closeFunction.close(resource);
} catch (Exception e) {
Exceptions.throwChecked(e);
}
}
/**
* Creates a new {@link Res} instance.
*
* @param closeFunction the function for releasing the resource
* @param resource the resource instance
* @param <R> the resource type
* @return
*/
public static <R> Res<R> res(CloseFunction<R> closeFunction, R resource) {
return new Res<>(closeFunction, resource);
}
@Override
public <T extends Throwable> Res<R> expected() throws T {
return this;
}
/**
* Functional interface for closing a resource.
*
* @param <R> the resource type
* @see Res#res(CloseFunction, Object)
*/
@FunctionalInterface
public interface CloseFunction<R> {
/**
* Releases the resource argument.
*
* @param resource the resource to close
* @throws Exception on error
*/
void close(R resource) throws Exception;
}
}