Skip to content

Commit 7ecca22

Browse files
committed
Add builders and avoid creating more constructors for all permutations
of current options. In the future new options should be added via builder and no new public or protected constructors should be added for input streams, output streams, readers, and writers. Likely the same for filters.
1 parent b51e419 commit 7ecca22

44 files changed

Lines changed: 3218 additions & 957 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/changes/changes.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,9 @@ The <action> type attribute can be add,update,fix,remove.
468468
<action dev="ggregory" type="add" due-to="Gary Gregory">
469469
Add FileSystem.getBlockSize().
470470
</action>
471+
<action dev="ggregory" type="add" due-to="Gary Gregory">
472+
Add builders and avoid creating more constructors for all permutations of current options.
473+
</action>
471474
<!-- UPDATE -->
472475
<action dev="kinow" type="update" due-to="Dependabot, Gary Gregory">
473476
Bump actions/cache from 2.1.6 to 3.0.10 #307, #337, #393.
Lines changed: 276 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,276 @@
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.build;
19+
20+
import java.io.File;
21+
import java.io.IOException;
22+
import java.io.InputStream;
23+
import java.io.OutputStream;
24+
import java.io.Reader;
25+
import java.io.Writer;
26+
import java.net.URI;
27+
import java.nio.charset.Charset;
28+
import java.nio.file.Files;
29+
import java.nio.file.OpenOption;
30+
import java.nio.file.Path;
31+
import java.nio.file.Paths;
32+
import java.util.Objects;
33+
34+
/**
35+
* Abstracts the origin of data for builders like a {@link File}, {@link Path}, and so on.
36+
*
37+
* @param <T> the type of instances to build.
38+
* @param <B> the type of builder subclass.
39+
* @since 2.12.0
40+
*/
41+
public abstract class AbstractOrigin<T, B extends AbstractOrigin<T, B>> extends AbstractSupplier<T, B> {
42+
43+
/**
44+
* A {@link File} origin.
45+
*/
46+
public static class FileOrigin extends AbstractOrigin<File, FileOrigin> {
47+
48+
public FileOrigin(final File origin) {
49+
super(origin);
50+
}
51+
52+
@Override
53+
public File getFile() {
54+
return get();
55+
}
56+
57+
@Override
58+
public Path getPath() {
59+
return get().toPath();
60+
}
61+
62+
}
63+
64+
/**
65+
* An {@link InputStream} origin.
66+
* <p>
67+
* This origin cannot provide other aspects.
68+
* </p>
69+
*/
70+
public static class InputStreamOrigin extends AbstractOrigin<InputStream, InputStreamOrigin> {
71+
72+
public InputStreamOrigin(final InputStream origin) {
73+
super(origin);
74+
}
75+
76+
@Override
77+
public InputStream getInputStream(final OpenOption... options) {
78+
return get();
79+
}
80+
81+
}
82+
83+
/**
84+
* An {@link OutputStream} origin.
85+
* <p>
86+
* This origin cannot provide other aspects.
87+
* </p>
88+
*/
89+
public static class OutputStreamOrigin extends AbstractOrigin<OutputStream, OutputStreamOrigin> {
90+
91+
public OutputStreamOrigin(final OutputStream origin) {
92+
super(origin);
93+
}
94+
95+
@Override
96+
public OutputStream getOutputStream(final OpenOption... options) {
97+
return get();
98+
}
99+
100+
}
101+
102+
/**
103+
* A {@link Path} origin.
104+
*/
105+
public static class PathOrigin extends AbstractOrigin<Path, PathOrigin> {
106+
107+
public PathOrigin(final Path origin) {
108+
super(origin);
109+
}
110+
111+
@Override
112+
public File getFile() {
113+
return get().toFile();
114+
}
115+
116+
@Override
117+
public Path getPath() {
118+
return get();
119+
}
120+
121+
}
122+
123+
/**
124+
* An {@link Reader} origin.
125+
* <p>
126+
* This origin cannot provide other aspects.
127+
* </p>
128+
*/
129+
public static class ReaderOrigin extends AbstractOrigin<Reader, ReaderOrigin> {
130+
131+
public ReaderOrigin(final Reader origin) {
132+
super(origin);
133+
}
134+
135+
@Override
136+
public Reader getReader(final Charset charset) throws IOException {
137+
return get();
138+
}
139+
}
140+
141+
/**
142+
* A {@link URI} origin.
143+
*/
144+
public static class URIOrigin extends AbstractOrigin<URI, URIOrigin> {
145+
146+
public URIOrigin(final URI origin) {
147+
super(origin);
148+
}
149+
150+
@Override
151+
public URI get() {
152+
return origin;
153+
}
154+
155+
@Override
156+
public File getFile() {
157+
return getPath().toFile();
158+
}
159+
160+
@Override
161+
public Path getPath() {
162+
return Paths.get(get());
163+
}
164+
165+
}
166+
167+
/**
168+
* An {@link Writer} origin.
169+
* <p>
170+
* This origin cannot provide other aspects.
171+
* </p>
172+
*/
173+
public static class WriterOrigin extends AbstractOrigin<Writer, WriterOrigin> {
174+
175+
public WriterOrigin(final Writer origin) {
176+
super(origin);
177+
}
178+
179+
@Override
180+
public Writer getWriter(final Charset charset, final OpenOption... options) throws IOException {
181+
return get();
182+
}
183+
}
184+
185+
/**
186+
* The non-null origin.
187+
*/
188+
final T origin;
189+
190+
/**
191+
* Constructs a new instance for a subclass.
192+
*
193+
* @param origin The origin.
194+
*/
195+
protected AbstractOrigin(final T origin) {
196+
this.origin = Objects.requireNonNull(origin, "origin");
197+
}
198+
199+
/**
200+
* Gets the origin.
201+
*
202+
* @return the origin.
203+
*/
204+
@Override
205+
public T get() {
206+
return origin;
207+
}
208+
209+
/**
210+
* Gets a new Reader on the origin, buffered by default.
211+
*
212+
* @param charset the charset to use for decoding
213+
* @return a new Reader on the origin.
214+
* @throws IOException if an I/O error occurs opening the file.
215+
*/
216+
public Reader getReader(final Charset charset) throws IOException {
217+
return Files.newBufferedReader(getPath(), charset);
218+
}
219+
220+
/**
221+
* Gets a new Writer on the origin, buffered by default.
222+
*
223+
* @param charset the charset to use for encoding
224+
* @param options options specifying how the file is opened
225+
* @return a new Writer on the origin.
226+
* @throws IOException if an I/O error occurs opening or creating the file.
227+
*/
228+
public Writer getWriter(final Charset charset, final OpenOption... options) throws IOException {
229+
return Files.newBufferedWriter(getPath(), charset, options);
230+
}
231+
232+
/**
233+
* Gets this origin as a Path, if possible.
234+
*
235+
* @return this origin as a Path, if possible.
236+
*/
237+
public File getFile() {
238+
throw new UnsupportedOperationException(origin.toString());
239+
}
240+
241+
/**
242+
* Gets this origin as an InputStream, if possible.
243+
*
244+
* @param options options specifying how the file is opened
245+
* @return this origin as an InputStream, if possible.
246+
* @throws IOException if an I/O error occurs.
247+
*/
248+
public InputStream getInputStream(final OpenOption... options) throws IOException {
249+
return Files.newInputStream(getPath(), options);
250+
}
251+
252+
/**
253+
* Gets this origin as an OutputStream, if possible.
254+
*
255+
* @param options options specifying how the file is opened
256+
* @return this origin as an OutputStream, if possible.
257+
* @throws IOException if an I/O error occurs.
258+
*/
259+
public OutputStream getOutputStream(final OpenOption... options) throws IOException {
260+
return Files.newOutputStream(getPath(), options);
261+
}
262+
263+
/**
264+
* Gets this origin as a Path, if possible.
265+
*
266+
* @return this origin as a Path\, if possible.
267+
*/
268+
public Path getPath() {
269+
throw new UnsupportedOperationException(origin.toString());
270+
}
271+
272+
@Override
273+
public String toString() {
274+
return origin.toString();
275+
}
276+
}

0 commit comments

Comments
 (0)