All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.signalfx.shaded.apache.commons.io.build.AbstractOrigin Maven / Gradle / Ivy

There is a newer version: 1.0.45
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.signalfx.shaded.apache.commons.io.build;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.RandomAccessFile;
import java.io.Reader;
import java.io.Writer;
import java.net.URI;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Objects;

import com.signalfx.shaded.apache.commons.io.IOUtils;
import com.signalfx.shaded.apache.commons.io.RandomAccessFileMode;
import com.signalfx.shaded.apache.commons.io.RandomAccessFiles;
import com.signalfx.shaded.apache.commons.io.input.ReaderInputStream;
import com.signalfx.shaded.apache.commons.io.output.WriterOutputStream;

/**
 * Abstracts the origin of data for builders like a {@link File}, {@link Path}, {@link Reader}, {@link Writer}, {@link InputStream}, {@link OutputStream}, and
 * {@link URI}.
 * 

* Some methods may throw {@link UnsupportedOperationException} if that method is not implemented in a concrete subclass, see {@link #getFile()} and * {@link #getPath()}. *

* * @param the type of instances to build. * @param the type of builder subclass. * @since 2.12.0 */ public abstract class AbstractOrigin> extends AbstractSupplier { /** * A {@code byte[]} origin. */ public static class ByteArrayOrigin extends AbstractOrigin { /** * Constructs a new instance for the given origin. * * @param origin The origin. */ public ByteArrayOrigin(final byte[] origin) { super(origin); } @Override public byte[] getByteArray() { // No conversion return get(); } @Override public InputStream getInputStream(final OpenOption... options) throws IOException { return new ByteArrayInputStream(origin); } @Override public Reader getReader(final Charset charset) throws IOException { return new InputStreamReader(getInputStream(), charset); } @Override public long size() throws IOException { return origin.length; } } /** * A {@link CharSequence} origin. */ public static class CharSequenceOrigin extends AbstractOrigin { /** * Constructs a new instance for the given origin. * * @param origin The origin. */ public CharSequenceOrigin(final CharSequence origin) { super(origin); } @Override public byte[] getByteArray() { // TODO Pass in a Charset? Consider if call sites actually need this. return origin.toString().getBytes(Charset.defaultCharset()); } @Override public CharSequence getCharSequence(final Charset charset) { // No conversion return get(); } @Override public InputStream getInputStream(final OpenOption... options) throws IOException { // TODO Pass in a Charset? Consider if call sites actually need this. return new ByteArrayInputStream(origin.toString().getBytes(Charset.defaultCharset())); // Needs [IO-795] CharSequenceInputStream.reset() only works once. // return CharSequenceInputStream.builder().setCharSequence(getCharSequence(Charset.defaultCharset())).get(); } @Override public Reader getReader(final Charset charset) throws IOException { return new InputStreamReader(getInputStream(), charset); } @Override public long size() throws IOException { return origin.length(); } } /** * A {@link File} origin. *

* Starting from this origin, you can get a byte array, a file, an input stream, an output stream, a path, a reader, and a writer. *

*/ public static class FileOrigin extends AbstractOrigin { /** * Constructs a new instance for the given origin. * * @param origin The origin. */ public FileOrigin(final File origin) { super(origin); } @Override public byte[] getByteArray(final long position, final int length) throws IOException { try (RandomAccessFile raf = RandomAccessFileMode.READ_ONLY.create(origin)) { return RandomAccessFiles.read(raf, position, length); } } @Override public File getFile() { // No conversion return get(); } @Override public Path getPath() { return get().toPath(); } } /** * An {@link InputStream} origin. *

* This origin cannot provide some of the other aspects. *

*/ public static class InputStreamOrigin extends AbstractOrigin { /** * Constructs a new instance for the given origin. * * @param origin The origin. */ public InputStreamOrigin(final InputStream origin) { super(origin); } @Override public byte[] getByteArray() throws IOException { return IOUtils.toByteArray(origin); } @Override public InputStream getInputStream(final OpenOption... options) { // No conversion return get(); } @Override public Reader getReader(final Charset charset) throws IOException { return new InputStreamReader(getInputStream(), charset); } } /** * An {@link OutputStream} origin. *

* This origin cannot provide some of the other aspects. *

*/ public static class OutputStreamOrigin extends AbstractOrigin { /** * Constructs a new instance for the given origin. * * @param origin The origin. */ public OutputStreamOrigin(final OutputStream origin) { super(origin); } @Override public OutputStream getOutputStream(final OpenOption... options) { // No conversion return get(); } @Override public Writer getWriter(final Charset charset, final OpenOption... options) throws IOException { return new OutputStreamWriter(origin, charset); } } /** * A {@link Path} origin. *

* Starting from this origin, you can get a byte array, a file, an input stream, an output stream, a path, a reader, and a writer. *

*/ public static class PathOrigin extends AbstractOrigin { /** * Constructs a new instance for the given origin. * * @param origin The origin. */ public PathOrigin(final Path origin) { super(origin); } @Override public byte[] getByteArray(final long position, final int length) throws IOException { try (RandomAccessFile raf = RandomAccessFileMode.READ_ONLY.create(origin)) { return RandomAccessFiles.read(raf, position, length); } } @Override public File getFile() { return get().toFile(); } @Override public Path getPath() { // No conversion return get(); } } /** * An {@link Reader} origin. *

* This origin cannot provide other aspects. *

*/ public static class ReaderOrigin extends AbstractOrigin { /** * Constructs a new instance for the given origin. * * @param origin The origin. */ public ReaderOrigin(final Reader origin) { super(origin); } @Override public byte[] getByteArray() throws IOException { // TODO Pass in a Charset? Consider if call sites actually need this. return IOUtils.toByteArray(origin, Charset.defaultCharset()); } @Override public CharSequence getCharSequence(final Charset charset) throws IOException { return IOUtils.toString(origin); } @Override public InputStream getInputStream(final OpenOption... options) throws IOException { // TODO Pass in a Charset? Consider if call sites actually need this. return ReaderInputStream.builder().setReader(origin).setCharset(Charset.defaultCharset()).get(); } @Override public Reader getReader(final Charset charset) throws IOException { // No conversion return get(); } } /** * A {@link URI} origin. */ public static class URIOrigin extends AbstractOrigin { /** * Constructs a new instance for the given origin. * * @param origin The origin. */ public URIOrigin(final URI origin) { super(origin); } @Override public File getFile() { return getPath().toFile(); } @Override public Path getPath() { return Paths.get(get()); } } /** * An {@link Writer} origin. *

* This origin cannot provide other aspects. *

*/ public static class WriterOrigin extends AbstractOrigin { /** * Constructs a new instance for the given origin. * * @param origin The origin. */ public WriterOrigin(final Writer origin) { super(origin); } @Override public OutputStream getOutputStream(final OpenOption... options) throws IOException { // TODO Pass in a Charset? Consider if call sites actually need this. return WriterOutputStream.builder().setWriter(origin).setCharset(Charset.defaultCharset()).get(); } @Override public Writer getWriter(final Charset charset, final OpenOption... options) throws IOException { // No conversion return get(); } } /** * The non-null origin. */ final T origin; /** * Constructs a new instance for a subclass. * * @param origin The origin. */ protected AbstractOrigin(final T origin) { this.origin = Objects.requireNonNull(origin, "origin"); } /** * Gets the origin. * * @return the origin. */ @Override public T get() { return origin; } /** * Gets this origin as a byte array, if possible. * * @return this origin as a byte array, if possible. * @throws IOException if an I/O error occurs. * @throws UnsupportedOperationException if the origin cannot be converted to a Path. */ public byte[] getByteArray() throws IOException { return Files.readAllBytes(getPath()); } /** * Gets this origin as a byte array, if possible. * * @param position the initial index of the range to be copied, inclusive. * @param length How many bytes to copy. * @return this origin as a byte array, if possible. * @throws UnsupportedOperationException if the origin cannot be converted to a Path. * @throws ArithmeticException if the {@code position} overflows an int * @throws IOException if an I/O error occurs. * @since 2.13.0 */ public byte[] getByteArray(final long position, final int length) throws IOException { final byte[] bytes = getByteArray(); // Checks for int overflow. final int start = Math.toIntExact(position); if (start < 0 || length < 0 || start + length < 0 || start + length > bytes.length) { throw new IllegalArgumentException("Couldn't read array (start: " + start + ", length: " + length + ", data length: " + bytes.length + ")."); } return Arrays.copyOfRange(bytes, start, start + length); } /** * Gets this origin as a byte array, if possible. * * @param charset The charset to use if conversion from bytes is needed. * @return this origin as a byte array, if possible. * @throws IOException if an I/O error occurs. * @throws UnsupportedOperationException if the origin cannot be converted to a Path. */ public CharSequence getCharSequence(final Charset charset) throws IOException { return new String(getByteArray(), charset); } /** * Gets this origin as a Path, if possible. * * @return this origin as a Path, if possible. * @throws UnsupportedOperationException if this method is not implemented in a concrete subclass. */ public File getFile() { throw new UnsupportedOperationException( String.format("%s#getFile() for %s origin %s", getClass().getSimpleName(), origin.getClass().getSimpleName(), origin)); } /** * Gets this origin as an InputStream, if possible. * * @param options options specifying how the file is opened * @return this origin as an InputStream, if possible. * @throws IOException if an I/O error occurs. * @throws UnsupportedOperationException if the origin cannot be converted to a Path. */ public InputStream getInputStream(final OpenOption... options) throws IOException { return Files.newInputStream(getPath(), options); } /** * Gets this origin as an OutputStream, if possible. * * @param options options specifying how the file is opened * @return this origin as an OutputStream, if possible. * @throws IOException if an I/O error occurs. * @throws UnsupportedOperationException if the origin cannot be converted to a Path. */ public OutputStream getOutputStream(final OpenOption... options) throws IOException { return Files.newOutputStream(getPath(), options); } /** * Gets this origin as a Path, if possible. * * @return this origin as a Path, if possible. * @throws UnsupportedOperationException if this method is not implemented in a concrete subclass. */ public Path getPath() { throw new UnsupportedOperationException( String.format("%s#getPath() for %s origin %s", getClass().getSimpleName(), origin.getClass().getSimpleName(), origin)); } /** * Gets a new Reader on the origin, buffered by default. * * @param charset the charset to use for decoding * @return a new Reader on the origin. * @throws IOException if an I/O error occurs opening the file. */ public Reader getReader(final Charset charset) throws IOException { return Files.newBufferedReader(getPath(), charset); } /** * Gets a new Writer on the origin, buffered by default. * * @param charset the charset to use for encoding * @param options options specifying how the file is opened * @return a new Writer on the origin. * @throws IOException if an I/O error occurs opening or creating the file. * @throws UnsupportedOperationException if the origin cannot be converted to a Path. */ public Writer getWriter(final Charset charset, final OpenOption... options) throws IOException { return Files.newBufferedWriter(getPath(), charset, options); } /** * Gets the size of the origin, if possible. * * @return the size of the origin in bytes or characters. * @throws IOException if an I/O error occurs. * @since 2.13.0 */ public long size() throws IOException { return Files.size(getPath()); } @Override public String toString() { return getClass().getSimpleName() + "[" + origin.toString() + "]"; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy