Skip to content

Commit a4373a8

Browse files
committed
Add UncheckedAppendable.
1 parent 6659feb commit a4373a8

4 files changed

Lines changed: 239 additions & 0 deletions

File tree

src/changes/changes.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ The <action> type attribute can be add,update,fix,remove.
120120
<action dev="ggregory" type="add" due-to="Gary Gregory">
121121
Add PathUtils.newOutputStream(Path, boolean).
122122
</action>
123+
<action dev="ggregory" type="add" due-to="Gary Gregory">
124+
Add UncheckedAppendable.
125+
</action>
123126
<!-- UPDATE -->
124127
<action dev="ggregory" type="update" due-to="Dependabot">
125128
Bump Maven Javadoc plugin from 3.2.0 to 3.3.0.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.commons.io.output;
19+
20+
import java.io.IOException;
21+
import java.io.UncheckedIOException;
22+
23+
/**
24+
* An {@link Appendable} that throws {@link UncheckedIOException} instead of {@link IOException}.
25+
*
26+
* @see Appendable
27+
* @see IOException
28+
* @see UncheckedIOException
29+
* @since 2.12.0
30+
*/
31+
public interface UncheckedAppendable extends Appendable {
32+
33+
/**
34+
* Creates a new instance on the given Appendable.
35+
*
36+
* @param appendable The Appendable to uncheck.
37+
* @return a new instance.
38+
*/
39+
public static UncheckedAppendable on(final Appendable appendable) {
40+
return new UncheckedAppendableImpl(appendable);
41+
}
42+
43+
/**
44+
* Rethrows {@link IOException} as {@link UncheckedIOException}.
45+
*/
46+
@Override
47+
UncheckedAppendable append(char c);
48+
49+
/**
50+
* Rethrows {@link IOException} as {@link UncheckedIOException}.
51+
*/
52+
@Override
53+
UncheckedAppendable append(CharSequence csq);
54+
55+
/**
56+
* Rethrows {@link IOException} as {@link UncheckedIOException}.
57+
*/
58+
@Override
59+
UncheckedAppendable append(CharSequence csq, int start, int end);
60+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.commons.io.output;
19+
20+
import java.io.IOException;
21+
import java.io.UncheckedIOException;
22+
import java.util.Objects;
23+
24+
/**
25+
* An {@link Appendable} implementation that throws {@link UncheckedIOException} instead of {@link IOException}.
26+
*
27+
* @see Appendable
28+
* @see IOException
29+
* @see UncheckedIOException
30+
* @since 2.12.0
31+
*/
32+
class UncheckedAppendableImpl implements UncheckedAppendable {
33+
34+
private final Appendable appendable;
35+
36+
UncheckedAppendableImpl(final Appendable appendable) {
37+
super();
38+
this.appendable = Objects.requireNonNull(appendable, "appendable");
39+
}
40+
41+
@Override
42+
public UncheckedAppendable append(final char c) {
43+
try {
44+
appendable.append(c);
45+
} catch (final IOException e) {
46+
throw new UncheckedIOException(String.valueOf(c), e);
47+
}
48+
return this;
49+
}
50+
51+
@Override
52+
public UncheckedAppendable append(final CharSequence csq) {
53+
try {
54+
appendable.append(csq);
55+
} catch (final IOException e) {
56+
throw new UncheckedIOException(Objects.toString(csq), e);
57+
}
58+
return this;
59+
}
60+
61+
@Override
62+
public UncheckedAppendable append(final CharSequence csq, final int start, final int end) {
63+
try {
64+
appendable.append(csq, start, end);
65+
} catch (final IOException e) {
66+
throw new UncheckedIOException(Objects.toString(csq), e);
67+
}
68+
return this;
69+
}
70+
71+
@Override
72+
public String toString() {
73+
return appendable.toString();
74+
}
75+
76+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.commons.io.output;
18+
19+
import static org.junit.jupiter.api.Assertions.assertEquals;
20+
import static org.junit.jupiter.api.Assertions.fail;
21+
22+
import java.io.IOException;
23+
import java.io.StringWriter;
24+
import java.io.UncheckedIOException;
25+
26+
import org.junit.jupiter.api.BeforeEach;
27+
import org.junit.jupiter.api.Test;
28+
29+
/**
30+
* JUnit Test Case for {@link BrokenWriter}.
31+
*/
32+
public class UncheckedAppendableTest {
33+
34+
private IOException exception;
35+
36+
private UncheckedAppendable appendableBroken;
37+
private UncheckedAppendable appendableString;
38+
39+
@SuppressWarnings("resource")
40+
@BeforeEach
41+
public void setUp() {
42+
exception = new IOException("test exception");
43+
appendableBroken = UncheckedAppendable.on(new BrokenWriter(exception));
44+
appendableString = UncheckedAppendable.on(new StringWriter());
45+
}
46+
47+
@Test
48+
public void testAppendChar() {
49+
appendableString.append('a').append('b');
50+
assertEquals("ab", appendableString.toString());
51+
}
52+
53+
@Test
54+
public void testAppendCharSequence() {
55+
appendableString.append("a").append("b");
56+
assertEquals("ab", appendableString.toString());
57+
}
58+
59+
@Test
60+
public void testAppendCharSequenceIndexed() {
61+
appendableString.append("a", 0, 1).append("b", 0, 1);
62+
assertEquals("ab", appendableString.toString());
63+
}
64+
65+
@Test
66+
public void testAppendCharSequenceIndexedThrows() {
67+
try {
68+
appendableBroken.append("a", 0, 1);
69+
fail("Expected exception not thrown.");
70+
} catch (final UncheckedIOException e) {
71+
assertEquals(exception, e.getCause());
72+
}
73+
}
74+
75+
@Test
76+
public void testAppendCharSequenceThrows() {
77+
try {
78+
appendableBroken.append("a");
79+
fail("Expected exception not thrown.");
80+
} catch (final UncheckedIOException e) {
81+
assertEquals(exception, e.getCause());
82+
}
83+
}
84+
85+
@Test
86+
public void testAppendCharThrows() {
87+
try {
88+
appendableBroken.append('a');
89+
fail("Expected exception not thrown.");
90+
} catch (final UncheckedIOException e) {
91+
assertEquals(exception, e.getCause());
92+
}
93+
}
94+
95+
@Test
96+
public void testToString() {
97+
assertEquals("ab", UncheckedAppendable.on(new StringWriter(2).append("ab")).toString());
98+
}
99+
100+
}

0 commit comments

Comments
 (0)