001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.io.output;
019
020import java.io.FilterOutputStream;
021import java.io.IOException;
022import java.io.OutputStream;
023import java.io.UncheckedIOException;
024
025import org.apache.commons.io.build.AbstractStreamBuilder;
026import org.apache.commons.io.function.Uncheck;
027
028/**
029 * A {@link FilterOutputStream} that throws {@link UncheckedIOException} instead of {@link UncheckedIOException}.
030 *
031 * @see FilterOutputStream
032 * @see UncheckedIOException
033 * @see UncheckedIOException
034 * @since 2.12.0
035 */
036public final class UncheckedFilterOutputStream extends FilterOutputStream {
037
038    /**
039     * Builds a new {@link UncheckedFilterOutputStream} instance.
040     * <p>
041     * Using File IO:
042     * </p>
043     * <pre>{@code
044     * UncheckedFilterOutputStream s = UncheckedFilterOutputStream.builder()
045     *   .setFile(file)
046     *   .get()}
047     * </pre>
048     * <p>
049     * Using NIO Path:
050     * </p>
051     * <pre>{@code
052     * UncheckedFilterOutputStream s = UncheckedFilterOutputStream.builder()
053     *   .setPath(path)
054     *   .get()}
055     * </pre>
056     */
057    public static class Builder extends AbstractStreamBuilder<UncheckedFilterOutputStream, Builder> {
058
059        /**
060         * Constructs a new instance.
061         *
062         * @throws UnsupportedOperationException if the origin cannot be converted to an OutputStream.
063         */
064        @SuppressWarnings("resource")
065        @Override
066        public UncheckedFilterOutputStream get() throws IOException {
067            return new UncheckedFilterOutputStream(getOrigin().getOutputStream());
068        }
069
070    }
071
072    /**
073     * Constructs a new {@link Builder}.
074     *
075     * @return a new {@link Builder}.
076     */
077    public static Builder builder() {
078        return new Builder();
079    }
080
081    /**
082     * Creates an output stream filter built on top of the specified underlying output stream.
083     *
084     * @param outputStream the underlying output stream, or {@code null} if this instance is to be created without an
085     *        underlying stream.
086     */
087    private UncheckedFilterOutputStream(final OutputStream outputStream) {
088        super(outputStream);
089    }
090
091    /**
092     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
093     */
094    @Override
095    public void close() throws UncheckedIOException {
096        Uncheck.run(super::close);
097    }
098
099    /**
100     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
101     */
102    @Override
103    public void flush() throws UncheckedIOException {
104        Uncheck.run(super::flush);
105    }
106
107    /**
108     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
109     */
110    @Override
111    public void write(final byte[] b) throws UncheckedIOException {
112        Uncheck.accept(super::write, b);
113    }
114
115    /**
116     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
117     */
118    @Override
119    public void write(final byte[] b, final int off, final int len) throws UncheckedIOException {
120        Uncheck.accept(super::write, b, off, len);
121    }
122
123    /**
124     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
125     */
126    @Override
127    public void write(final int b) throws UncheckedIOException {
128        Uncheck.accept(super::write, b);
129    }
130
131}