1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.io.build;
19
20 import java.io.ByteArrayInputStream;
21 import java.io.File;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.InputStreamReader;
25 import java.io.OutputStream;
26 import java.io.OutputStreamWriter;
27 import java.io.RandomAccessFile;
28 import java.io.Reader;
29 import java.io.Writer;
30 import java.net.URI;
31 import java.nio.charset.Charset;
32 import java.nio.file.Files;
33 import java.nio.file.OpenOption;
34 import java.nio.file.Path;
35 import java.nio.file.Paths;
36 import java.util.Arrays;
37 import java.util.Objects;
38
39 import org.apache.commons.io.IOUtils;
40 import org.apache.commons.io.RandomAccessFileMode;
41 import org.apache.commons.io.RandomAccessFiles;
42 import org.apache.commons.io.input.CharSequenceInputStream;
43 import org.apache.commons.io.input.CharSequenceReader;
44 import org.apache.commons.io.input.ReaderInputStream;
45 import org.apache.commons.io.output.WriterOutputStream;
46
47
48
49
50
51
52
53
54
55
56
57
58
59 public abstract class AbstractOrigin<T, B extends AbstractOrigin<T, B>> extends AbstractSupplier<T, B> {
60
61
62
63
64 public static class ByteArrayOrigin extends AbstractOrigin<byte[], ByteArrayOrigin> {
65
66
67
68
69
70
71 public ByteArrayOrigin(final byte[] origin) {
72 super(origin);
73 }
74
75 @Override
76 public byte[] getByteArray() {
77
78 return get();
79 }
80
81
82
83
84
85
86
87 @Override
88 public InputStream getInputStream(final OpenOption... options) throws IOException {
89 return new ByteArrayInputStream(origin);
90 }
91
92 @Override
93 public Reader getReader(final Charset charset) throws IOException {
94 return new InputStreamReader(getInputStream(), charset);
95 }
96
97 @Override
98 public long size() throws IOException {
99 return origin.length;
100 }
101
102 }
103
104
105
106
107 public static class CharSequenceOrigin extends AbstractOrigin<CharSequence, CharSequenceOrigin> {
108
109
110
111
112
113
114 public CharSequenceOrigin(final CharSequence origin) {
115 super(origin);
116 }
117
118 @Override
119 public byte[] getByteArray() {
120
121 return origin.toString().getBytes(Charset.defaultCharset());
122 }
123
124
125
126
127
128
129
130 @Override
131 public CharSequence getCharSequence(final Charset charset) {
132
133 return get();
134 }
135
136
137
138
139
140
141
142 @Override
143 public InputStream getInputStream(final OpenOption... options) throws IOException {
144
145 return CharSequenceInputStream.builder().setCharSequence(getCharSequence(Charset.defaultCharset())).get();
146 }
147
148
149
150
151
152
153
154 @Override
155 public Reader getReader(final Charset charset) throws IOException {
156 return new CharSequenceReader(get());
157 }
158
159 @Override
160 public long size() throws IOException {
161 return origin.length();
162 }
163
164 }
165
166
167
168
169
170
171
172 public static class FileOrigin extends AbstractOrigin<File, FileOrigin> {
173
174
175
176
177
178
179 public FileOrigin(final File origin) {
180 super(origin);
181 }
182
183 @Override
184 public byte[] getByteArray(final long position, final int length) throws IOException {
185 try (RandomAccessFile raf = RandomAccessFileMode.READ_ONLY.create(origin)) {
186 return RandomAccessFiles.read(raf, position, length);
187 }
188 }
189
190 @Override
191 public File getFile() {
192
193 return get();
194 }
195
196 @Override
197 public Path getPath() {
198 return get().toPath();
199 }
200
201 }
202
203
204
205
206
207
208
209 public static class InputStreamOrigin extends AbstractOrigin<InputStream, InputStreamOrigin> {
210
211
212
213
214
215
216 public InputStreamOrigin(final InputStream origin) {
217 super(origin);
218 }
219
220 @Override
221 public byte[] getByteArray() throws IOException {
222 return IOUtils.toByteArray(origin);
223 }
224
225
226
227
228
229
230
231 @Override
232 public InputStream getInputStream(final OpenOption... options) {
233
234 return get();
235 }
236
237 @Override
238 public Reader getReader(final Charset charset) throws IOException {
239 return new InputStreamReader(getInputStream(), charset);
240 }
241
242 }
243
244
245
246
247
248
249
250 public static class OutputStreamOrigin extends AbstractOrigin<OutputStream, OutputStreamOrigin> {
251
252
253
254
255
256
257 public OutputStreamOrigin(final OutputStream origin) {
258 super(origin);
259 }
260
261
262
263
264
265
266
267 @Override
268 public OutputStream getOutputStream(final OpenOption... options) {
269
270 return get();
271 }
272
273
274
275
276
277
278
279 @Override
280 public Writer getWriter(final Charset charset, final OpenOption... options) throws IOException {
281 return new OutputStreamWriter(origin, charset);
282 }
283 }
284
285
286
287
288
289
290
291 public static class PathOrigin extends AbstractOrigin<Path, PathOrigin> {
292
293
294
295
296
297
298 public PathOrigin(final Path origin) {
299 super(origin);
300 }
301
302 @Override
303 public byte[] getByteArray(final long position, final int length) throws IOException {
304 try (RandomAccessFile raf = RandomAccessFileMode.READ_ONLY.create(origin)) {
305 return RandomAccessFiles.read(raf, position, length);
306 }
307 }
308
309 @Override
310 public File getFile() {
311 return get().toFile();
312 }
313
314 @Override
315 public Path getPath() {
316
317 return get();
318 }
319
320 }
321
322
323
324
325
326
327
328 public static class ReaderOrigin extends AbstractOrigin<Reader, ReaderOrigin> {
329
330
331
332
333
334
335 public ReaderOrigin(final Reader origin) {
336 super(origin);
337 }
338
339 @Override
340 public byte[] getByteArray() throws IOException {
341
342 return IOUtils.toByteArray(origin, Charset.defaultCharset());
343 }
344
345
346
347
348
349
350
351 @Override
352 public CharSequence getCharSequence(final Charset charset) throws IOException {
353 return IOUtils.toString(origin);
354 }
355
356
357
358
359
360
361
362 @Override
363 public InputStream getInputStream(final OpenOption... options) throws IOException {
364
365 return ReaderInputStream.builder().setReader(origin).setCharset(Charset.defaultCharset()).get();
366 }
367
368
369
370
371
372
373
374 @Override
375 public Reader getReader(final Charset charset) throws IOException {
376
377 return get();
378 }
379 }
380
381
382
383
384 public static class URIOrigin extends AbstractOrigin<URI, URIOrigin> {
385
386
387
388
389
390
391 public URIOrigin(final URI origin) {
392 super(origin);
393 }
394
395 @Override
396 public File getFile() {
397 return getPath().toFile();
398 }
399
400 @Override
401 public Path getPath() {
402 return Paths.get(get());
403 }
404
405 }
406
407
408
409
410
411
412
413 public static class WriterOrigin extends AbstractOrigin<Writer, WriterOrigin> {
414
415
416
417
418
419
420 public WriterOrigin(final Writer origin) {
421 super(origin);
422 }
423
424
425
426
427
428
429
430 @Override
431 public OutputStream getOutputStream(final OpenOption... options) throws IOException {
432
433 return WriterOutputStream.builder().setWriter(origin).setCharset(Charset.defaultCharset()).get();
434 }
435
436
437
438
439
440
441
442
443
444
445 @Override
446 public Writer getWriter(final Charset charset, final OpenOption... options) throws IOException {
447
448 return get();
449 }
450 }
451
452
453
454
455 final T origin;
456
457
458
459
460
461
462 protected AbstractOrigin(final T origin) {
463 this.origin = Objects.requireNonNull(origin, "origin");
464 }
465
466
467
468
469
470
471 @Override
472 public T get() {
473 return origin;
474 }
475
476
477
478
479
480
481
482
483 public byte[] getByteArray() throws IOException {
484 return Files.readAllBytes(getPath());
485 }
486
487
488
489
490
491
492
493
494
495
496
497
498 public byte[] getByteArray(final long position, final int length) throws IOException {
499 final byte[] bytes = getByteArray();
500
501 final int start = Math.toIntExact(position);
502 if (start < 0 || length < 0 || start + length < 0 || start + length > bytes.length) {
503 throw new IllegalArgumentException("Couldn't read array (start: " + start + ", length: " + length + ", data length: " + bytes.length + ").");
504 }
505 return Arrays.copyOfRange(bytes, start, start + length);
506 }
507
508
509
510
511
512
513
514
515
516 public CharSequence getCharSequence(final Charset charset) throws IOException {
517 return new String(getByteArray(), charset);
518 }
519
520
521
522
523
524
525
526 public File getFile() {
527 throw new UnsupportedOperationException(
528 String.format("%s#getFile() for %s origin %s", getSimpleName(), origin.getClass().getSimpleName(), origin));
529 }
530
531
532
533
534
535
536
537
538
539 public InputStream getInputStream(final OpenOption... options) throws IOException {
540 return Files.newInputStream(getPath(), options);
541 }
542
543
544
545
546
547
548
549
550
551 public OutputStream getOutputStream(final OpenOption... options) throws IOException {
552 return Files.newOutputStream(getPath(), options);
553 }
554
555
556
557
558
559
560
561 public Path getPath() {
562 throw new UnsupportedOperationException(
563 String.format("%s#getPath() for %s origin %s", getSimpleName(), origin.getClass().getSimpleName(), origin));
564 }
565
566
567
568
569
570
571
572
573 public Reader getReader(final Charset charset) throws IOException {
574 return Files.newBufferedReader(getPath(), charset);
575 }
576
577 private String getSimpleName() {
578 return getClass().getSimpleName();
579 }
580
581
582
583
584
585
586
587
588
589
590 public Writer getWriter(final Charset charset, final OpenOption... options) throws IOException {
591 return Files.newBufferedWriter(getPath(), charset, options);
592 }
593
594
595
596
597
598
599
600
601 public long size() throws IOException {
602 return Files.size(getPath());
603 }
604
605 @Override
606 public String toString() {
607 return getSimpleName() + "[" + origin.toString() + "]";
608 }
609 }