Skip to content

Commit cd41159

Browse files
committed
Add support for threaded use of Try.withResources() for up to 3 arguments.
3 arguments is probably enough to cover common scenarios/use cases such as database related resource management (Connection, PreparedStatement, ResultSet).
1 parent 26181f1 commit cd41159

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed

src/main/java/io/vavr/control/Try.java

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,6 +1382,19 @@ public static <T1 extends AutoCloseable, T2 extends AutoCloseable> WithResources
13821382
return new WithResources2<>(t1Supplier, t2Supplier);
13831383
}
13841384

1385+
/**
1386+
* Creates a {@code Try}-with-resources builder that operates on two {@link AutoCloseable} chained (dependent) resources.
1387+
*
1388+
* @param t1Supplier The supplier of the 1st resource.
1389+
* @param t2Function A function which takes the supply of t1 and supplies the 2nd resource.
1390+
* @param <T1> Type of the 1st resource.
1391+
* @param <T2> Type of the 2nd resource.
1392+
* @return a new {@link WithThreadedResources2} instance.
1393+
*/
1394+
public static <T1 extends AutoCloseable, T2 extends AutoCloseable> WithThreadedResources2<T1, T2> withResources(CheckedFunction0<? extends T1> t1Supplier, CheckedFunction1<T1, ? extends T2> t2Function) {
1395+
return new WithThreadedResources2<>(t1Supplier, t2Function);
1396+
}
1397+
13851398
/**
13861399
* Creates a {@code Try}-with-resources builder that operates on three {@link AutoCloseable} resources.
13871400
*
@@ -1397,6 +1410,21 @@ public static <T1 extends AutoCloseable, T2 extends AutoCloseable, T3 extends Au
13971410
return new WithResources3<>(t1Supplier, t2Supplier, t3Supplier);
13981411
}
13991412

1413+
/**
1414+
* Creates a {@code Try}-with-resources builder that operates on three {@link AutoCloseable} chained (dependent) resources.
1415+
*
1416+
* @param t1Supplier The supplier of the 1st resource.
1417+
* @param t2Function A function which takes a supply of the 1st resource and supplies the 2nd resource.
1418+
* @param t3Function A function which takes a supply of the 2nd resource and supplies the 3rd resource.
1419+
* @param <T1> Type of the 1st resource.
1420+
* @param <T2> Type of the 2nd resource.
1421+
* @param <T3> Type of the 3rd resource.
1422+
* @return a new {@link WithThreadedResources3} instance.
1423+
*/
1424+
public static <T1 extends AutoCloseable, T2 extends AutoCloseable, T3 extends AutoCloseable> WithThreadedResources3<T1, T2, T3> withResources(CheckedFunction0<? extends T1> t1Supplier, CheckedFunction1<T1, ? extends T2> t2Function, CheckedFunction1<T2, ? extends T3> t3Function) {
1425+
return new WithThreadedResources3<>(t1Supplier, t2Function, t3Function);
1426+
}
1427+
14001428
/**
14011429
* Creates a {@code Try}-with-resources builder that operates on four {@link AutoCloseable} resources.
14021430
*
@@ -1565,6 +1593,39 @@ public <R> Try<R> of(CheckedFunction2<? super T1, ? super T2, ? extends R> f) {
15651593
}
15661594
}
15671595

1596+
/**
1597+
* A {@code Try}-with-resources builder that operates on two {@link AutoCloseable} threaded (dependent) resources.
1598+
*
1599+
* @param <T1> Type of the 1st resource.
1600+
* @param <T2> Type of the 2nd resource.
1601+
*/
1602+
public static final class WithThreadedResources2<T1 extends AutoCloseable, T2 extends AutoCloseable> {
1603+
1604+
private final CheckedFunction0<? extends T1> t1Supplier;
1605+
private final CheckedFunction1<T1, ? extends T2> t2Function;
1606+
1607+
private WithThreadedResources2(CheckedFunction0<? extends T1> t1Supplier, CheckedFunction1<T1, ? extends T2> t2Function) {
1608+
this.t1Supplier = t1Supplier;
1609+
this.t2Function = t2Function;
1610+
}
1611+
1612+
/**
1613+
* Wraps the result of a computation that may fail in a {@code Try}.
1614+
*
1615+
* @param f A computation that takes two {@code AutoClosable} resources.
1616+
* @param <R> Result type of the computation.
1617+
* @return A new {@code Try} instance.
1618+
*/
1619+
@SuppressWarnings("try")/* https://bugs.openjdk.java.net/browse/JDK-8155591 */
1620+
public <R> Try<R> of(CheckedFunction1<? super T2, ? extends R> f) {
1621+
return Try.of(() -> {
1622+
try (T1 t1 = t1Supplier.apply(); T2 t2 = t2Function.apply(t1)) {
1623+
return f.apply(t2);
1624+
}
1625+
});
1626+
}
1627+
}
1628+
15681629
/**
15691630
* A {@code Try}-with-resources builder that operates on three {@link AutoCloseable} resources.
15701631
*
@@ -1601,6 +1662,42 @@ public <R> Try<R> of(CheckedFunction3<? super T1, ? super T2, ? super T3, ? exte
16011662
}
16021663
}
16031664

1665+
/**
1666+
* A {@code Try}-with-resources builder that operates on three {@link AutoCloseable} threaded (dependent) resources.
1667+
*
1668+
* @param <T1> Type of the 1st resource.
1669+
* @param <T2> Type of the 2nd resource.
1670+
* @param <T3> Type of the 3rd resource.
1671+
*/
1672+
public static final class WithThreadedResources3<T1 extends AutoCloseable, T2 extends AutoCloseable, T3 extends AutoCloseable> {
1673+
1674+
private final CheckedFunction0<? extends T1> t1Supplier;
1675+
private final CheckedFunction1<T1, ? extends T2> t2Function;
1676+
private final CheckedFunction1<T2, ? extends T3> t3Function;
1677+
1678+
private WithThreadedResources3(CheckedFunction0<? extends T1> t1Supplier, CheckedFunction1<T1, ? extends T2> t2Function, CheckedFunction1<T2, ? extends T3> t3Function) {
1679+
this.t1Supplier = t1Supplier;
1680+
this.t2Function = t2Function;
1681+
this.t3Function = t3Function;
1682+
}
1683+
1684+
/**
1685+
* Wraps the result of a computation that may fail in a {@code Try}.
1686+
*
1687+
* @param f A computation that takes three {@code AutoClosable} resources.
1688+
* @param <R> Result type of the computation.
1689+
* @return A new {@code Try} instance.
1690+
*/
1691+
@SuppressWarnings("try")/* https://bugs.openjdk.java.net/browse/JDK-8155591 */
1692+
public <R> Try<R> of(CheckedFunction1<? super T3, ? extends R> f) {
1693+
return Try.of(() -> {
1694+
try (T1 t1 = t1Supplier.apply(); T2 t2 = t2Function.apply(t1); T3 t3 = t3Function.apply(t2)) {
1695+
return f.apply(t3);
1696+
}
1697+
});
1698+
}
1699+
}
1700+
16041701
/**
16051702
* A {@code Try}-with-resources builder that operates on four {@link AutoCloseable} resources.
16061703
*

src/test/java/io/vavr/control/TryTest.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,50 @@ public void shouldCreateFailureTryWithResources8() {
623623
assertThat(closeable8.isClosed).isTrue();
624624
}
625625

626+
@Test
627+
public void shouldCreateSuccessTryWithThreadedResources2() {
628+
final Closeable<Integer> closeable1 = Closeable.of(1);
629+
final Closeable<Integer> closeable2 = Closeable.of(2);
630+
final Try<String> actual = Try.withResources(() -> closeable1, i1 -> closeable2).of(i2 -> "" + i2.value);
631+
assertThat(actual).isEqualTo(Success("2"));
632+
assertThat(closeable1.isClosed).isTrue();
633+
assertThat(closeable2.isClosed).isTrue();
634+
}
635+
636+
@Test
637+
public void shouldCreateFailureTryWithThreadedResources2() {
638+
final Closeable<Integer> closeable1 = Closeable.of(1);
639+
final Closeable<Integer> closeable2 = Closeable.of(2);
640+
final Try<?> actual = Try.withResources(() -> closeable1, i1 -> closeable2).of(i2 -> { throw new Error(); });
641+
assertThat(actual.isFailure()).isTrue();
642+
assertThat(closeable1.isClosed).isTrue();
643+
assertThat(closeable2.isClosed).isTrue();
644+
}
645+
646+
@Test
647+
public void shouldCreateSuccessTryWithChainedResources3() {
648+
final Closeable<Integer> closeable1 = Closeable.of(1);
649+
final Closeable<Integer> closeable2 = Closeable.of(2);
650+
final Closeable<Integer> closeable3 = Closeable.of(3);
651+
final Try<String> actual = Try.withResources(() -> closeable1, i1 -> closeable2, i2 -> closeable3).of(i3 -> "" + i3.value);
652+
assertThat(actual).isEqualTo(Success("3"));
653+
assertThat(closeable1.isClosed).isTrue();
654+
assertThat(closeable2.isClosed).isTrue();
655+
assertThat(closeable3.isClosed).isTrue();
656+
}
657+
658+
@Test
659+
public void shouldCreateFailureTryWithThreadedResources3() {
660+
final Closeable<Integer> closeable1 = Closeable.of(1);
661+
final Closeable<Integer> closeable2 = Closeable.of(2);
662+
final Closeable<Integer> closeable3 = Closeable.of(3);
663+
final Try<?> actual = Try.withResources(() -> closeable1, i1 -> closeable2, i2 -> closeable3).of(i3 -> { throw new Error(); });
664+
assertThat(actual.isFailure()).isTrue();
665+
assertThat(closeable1.isClosed).isTrue();
666+
assertThat(closeable2.isClosed).isTrue();
667+
assertThat(closeable3.isClosed).isTrue();
668+
}
669+
626670
// -- Failure.Cause
627671

628672
@Test(expected = InterruptedException.class)

0 commit comments

Comments
 (0)