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 * <p>
031 * To build an instance, see {@link Builder}.
032 * </p>
033 *
034 * @see FilterOutputStream
035 * @see UncheckedIOException
036 * @see UncheckedIOException
037 * @since 2.12.0
038 */
039public final class UncheckedFilterOutputStream extends FilterOutputStream {
040
041    /**
042     * Builds a new {@link UncheckedFilterOutputStream} instance.
043     * <p>
044     * Using File IO:
045     * </p>
046     * <pre>{@code
047     * UncheckedFilterOutputStream s = UncheckedFilterOutputStream.builder()
048     *   .setFile(file)
049     *   .get();}
050     * </pre>
051     * <p>
052     * Using NIO Path:
053     * </p>
054     * <pre>{@code
055     * UncheckedFilterOutputStream s = UncheckedFilterOutputStream.builder()
056     *   .setPath(path)
057     *   .get();}
058     * </pre>
059     */
060    public static class Builder extends AbstractStreamBuilder<UncheckedFilterOutputStream, Builder> {
061
062        /**
063         * Constructs a new instance.
064         * <p>
065         * This builder use the aspect OutputStream and OpenOption[].
066         * </p>
067         * <p>
068         * You must provide an origin that can be converted to an OutputStream by this builder, otherwise, this call will throw an
069         * {@link UnsupportedOperationException}.
070         * </p>
071         *
072         * @return a new instance.
073         * @throws UnsupportedOperationException if the origin cannot provide an OutputStream.
074         * @see #getOutputStream()
075         */
076        @SuppressWarnings("resource")
077        @Override
078        public UncheckedFilterOutputStream get() throws IOException {
079            return new UncheckedFilterOutputStream(getOutputStream());
080        }
081
082    }
083
084    /**
085     * Constructs a new {@link Builder}.
086     *
087     * @return a new {@link Builder}.
088     */
089    public static Builder builder() {
090        return new Builder();
091    }
092
093    /**
094     * Constructs an output stream filter built on top of the specified underlying output stream.
095     *
096     * @param outputStream the underlying output stream, or {@code null} if this instance is to be created without an
097     *        underlying stream.
098     */
099    private UncheckedFilterOutputStream(final OutputStream outputStream) {
100        super(outputStream);
101    }
102
103    /**
104     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
105     */
106    @Override
107    public void close() throws UncheckedIOException {
108        Uncheck.run(super::close);
109    }
110
111    /**
112     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
113     */
114    @Override
115    public void flush() throws UncheckedIOException {
116        Uncheck.run(super::flush);
117    }
118
119    /**
120     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
121     */
122    @Override
123    public void write(final byte[] b) throws UncheckedIOException {
124        Uncheck.accept(super::write, b);
125    }
126
127    /**
128     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
129     */
130    @Override
131    public void write(final byte[] b, final int off, final int len) throws UncheckedIOException {
132        Uncheck.accept(super::write, b, off, len);
133    }
134
135    /**
136     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
137     */
138    @Override
139    public void write(final int b) throws UncheckedIOException {
140        Uncheck.accept(super::write, b);
141    }
142
143}